В C# можно ли уведомлять заблокированный / разблокированный объект? - PullRequest
0 голосов
/ 17 апреля 2020

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

object myLockObj = new SpecialLockNotifyClass("Bob");
lock (myLockObj)
{
   Console.WriteLine("Hello");
}

И результат, который вы получите:

Trying to lock Bob.
Bob is locked.
Hello.
Bob is unlocked.

Идея имеет два значения:

1) Настройте его так, чтобы можно было видеть, когда что-то пытается заблокировать (видя «пытающееся» сообщение »и ожидая бесконечно (не видя« заблокированное »сообщение) везде используется блокировка

2) Отключите выходы и вернитесь к стандартной блокировке, если вы уверены, что проблемы с блокировкой устранены.

Ответы [ 2 ]

2 голосов
/ 17 апреля 2020

lock - это просто синтактика c сахар для Monitor.Enter / Monitor.Exit.

Вы можете обернуть доступ к монитору в пользовательский тип Disposable и заменить свой * Блок 1006 * с блоком using. EG

    sealed class MyLock : IDisposable
    {
        private object syncRoot;
        bool lockWasTaken = false;

        public MyLock(object syncRoot)
        {
            this.syncRoot = syncRoot;
            BeforeLock();
            Monitor.Enter(syncRoot, ref lockWasTaken);
        }
        public void Exit()
        {
            if (lockWasTaken)
            {
                Monitor.Exit(syncRoot);
                lockWasTaken = false;
                AfterUnlock();
            }
        }

        void BeforeLock()
        {
            //...
        }

        void AfterUnlock()
        {
            //...
        }

        void IDisposable.Dispose()
        {
            Exit();
        }
    }

Вы можете даже обернуть это в методе Extension и написать:

using (foo.Lock())
{
}

Или, если вы просто хотите отслеживать попытки блокировки объекта, вы можете заменить

lock(foo) { . . .}

с

lock(TrackLock(foo))  { . . .}

, где

public static object TrackLock(object o)
{
    Console.WriteLine($"Locking {o.ToString()}");
    return o;
}
0 голосов
/ 17 апреля 2020

Является ли просто перемещение оператора блокировки в функцию параметром?

object myLockObj = new SpecialLockNotifyClass("Bob");

LockObj(myLockObj);

//
void LockObj(NotifyClassAbstract obj){
   // Notify
   Console.WriteLine($"Ur Object {obj.name} has been locked");

   // Do the lock
   lock (myLockObj)
   {
      Console.WriteLine("Hello");
   }
}

Вы можете даже использовать его как функцию в SpecialLockNotifyClass.

 myLockObj.Lock();

Или вы можете создать Метод расширения

public static class LockExtentions {
       public static void Lock(this LockClasss myLockObj){
       // Notify


          Console.WriteLine($"Ur Object {obj.name} has been locked");

          // Do the lock
          lock (myLockObj)
          {
              Console.WriteLine("Hello");
          }
     }
 }
...