Не использовать System.Threading.Timer для синхронизации? - PullRequest
2 голосов
/ 20 января 2012

У меня есть код, похожий на этот:

using System.Threading;

public sealed class MyClass : IDisposable {
    private readonly Timer _timer;

   public MyClass() {
        _timer = new Timer(MyCallback);
   }

   public void SomeMethod() {
       lock (_timer) {
           ...
       }
   }

   ...

}

Когда я запускаю анализ кода (FxCop), я получаю сообщение об ошибке
CA2002 : Microsoft.Reliability : 'MyClass.SomeMethod' locks on a reference of type 'Timer'. Replace this with a lock against an object with strong-identity.

Я нашел некоторую документацию здесь .

Говорят, что объект имеет слабую идентичность, когда к нему можно получить прямой доступ через границы домена приложения.

Как получить доступ к моему объекту таймера через домены приложений?Единственная причина, по которой я могу придумать, заключается в том, что класс Timer оборачивает некоторый глобальный системный дескриптор, но я не понимаю, как этот дескриптор участвует в блокировке.

На странице документации есть список слабых классов, ноТаймер не упоминается.MemomoryStream также отсутствует в списке, но он включен в примеры.Как локальный объект MemoryStream может быть слабым?

Ответы [ 2 ]

4 голосов
/ 20 января 2012

Timer extends MarshalByRefObject, поэтому я подозреваю, что поэтому жалуется.

Лично я бы рекомендовал блокировать только частный объект, который only Ваш код может знать о:

using System.Threading;

public sealed class MyClass : IDisposable {
    private readonly Timer _timer;
    private readonly object _mutex = new object();

   public MyClass() {
        _timer = new Timer(MyCallback);
   }

   public void SomeMethod() {
       lock (_mutex) {
           ...
       }
   }

   ...
}

Таким образом, вам не нужно беспокоиться о том, решит ли Timer заблокировать this и т. д.

2 голосов
/ 20 января 2012

Вы не можете быть уверены, что Timer не блокируется на своем экземпляре.Лучше всего использовать только new object().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...