代码之家  ›  专栏  ›  技术社区  ›  Guillaume

.net4,监视器.enter(lockobject,acquiredlock)

  •  3
  • Guillaume  · 技术社区  · 15 年前

    在NET4中, Monitor.Enter(Object) 标记为已过时:

    [ObsoleteAttribute("This method does not allow its caller to reliably release the lock.  Please use an overload with a lockTaken argument instead.")]
    public static void Enter(
        Object obj
    )
    

    还有一种新方法 Monitor.Enter(lockObject, acquiredLock) 使用此用法:

    bool acquiredLock = false;
    
    try
    {
        Monitor.Enter(lockObject, ref acquiredLock);
    
        // Code that accesses resources that are protected by the lock.
    
    }
    finally
    {
        if (acquiredLock)
        {
            Monitor.Exit(lockObject);
        }
    }
    

    我以前是这样做的:

    Monitor.Enter(lockObject);
    try
    {
    
        // Code that accesses resources that are protected by the lock.
    }
    finally
    {
        Monitor.Exit(lockObject);
    }
    

    这是错的吗?为什么? 可能是在进入后但在尝试前的一段插曲?
    正如eamon-nerbonne所问的:如果在monitor.exit之前的finally中有一个异步异常,会发生什么?

    答: ThreadAbortException

    当引发此异常时, 运行时最终执行所有 在结束线程之前阻止。

    1 回复  |  直到 13 年前
        1
  •  5
  •   Jon Skeet    15 年前

    正如你在问题的最后所建议的,问题是 asynchronous exception 可能在呼叫后引发 Monitor.Enter 但在你进入 try 块。

    新的做事方法确保无论发生什么,你都能击中最后一个挡块并释放锁。 如果 你得到了它。(如果 进入监视器 例如,引发异常。)

    IIRC,这是 lock 以.NET 4.0为目标时使用关键字。