在C#中,可以通知对象locked/unlocked吗?

In C#, can object being locked/unlocked be notified?

问题是,我可以创建一个 class 在锁定和解锁时收到通知的

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

你会得到的输出是:

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

这个想法有两个方面:

1) 设置它以便可以看到什么时候试图锁定(通过查看 "trying" 消息”并无限期地等待(通过看不到 "locked" 消息) 无处不在 锁被使用

2) 当认为死锁问题已解决时,关闭输出并切换回标准锁定。

简单地将 lock 语句移动到函数中是一种选择吗?

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");
          }
     }
 }

lock 只是 syntactic sugar for Monitor.Enter/Monitor.Exit.

您可以将 Monitor 访问包装在自定义 Disposable 类型中,并将 lock 块替换为 using 块。乙

    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();
        }
    }

您甚至可以将其包装在扩展方法中并编写:

using (foo.Lock())
{
}

或者,如果您只想跟踪锁定对象的尝试,您可以替换

lock(foo) { . . .}

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

哪里

public static object TrackLock(object o)
{
    Console.WriteLine($"Locking {o.ToString()}");
    return o;
}