Monitor.TryEnter(object) 和 Monitor.TryEnter(object, ref bool) 之间存在什么重要区别?

发布于 2024-09-18 12:38:39 字数 1207 浏览 15 评论 0原文

看来这些代码片段的行为应该相同:

1: Monitor.TryEnter(object)

if (Monitor.TryEnter(lockObject))
{
    try
    {
        DoSomething();
    }
    finally
    {
        Monitor.Exit(lockObject);
    }
}

2: Monitor.TryEnter(object, ref bool) - 在 .NET 4.0 中引入,

bool lockAcquired;
try
{
    Monitor.TryEnter(lockObject, ref lockAcquired);
    if (lockAcquired)
    {
        DoSomething();
    }
}
finally
{
    if (lockAcquired)
    {
        Monitor.Exit(lockObject);
    }
}

我从 MSDN 文档中看到 采用 ref bool 参数的重载

如果由于以下原因未获得锁定 抛出异常,变量 为 lockTaken 参数指定 此方法结束后为 false。这 允许程序确定,在 所有情况,是否有必要 释放锁。

但文档还指出,仅采用 object 参数的重载不会引发除 ArgumentNullException 之外的异常。因此,如果上面的代码片段 1 中抛出异常,那可能只是因为 lockObjectnull,在这种情况下没有锁无论如何,都会被获取(并且 TryEnter 会返回 false),因此不需要 Monitor.Exit 调用。

显然,他们不会无缘无故地引入这种过载。那么 Monitor.TryEnter(object, ref bool) 方法旨在解决什么场景?

It seems that these code snippets ought to behave identically:

1: Monitor.TryEnter(object)

if (Monitor.TryEnter(lockObject))
{
    try
    {
        DoSomething();
    }
    finally
    {
        Monitor.Exit(lockObject);
    }
}

2: Monitor.TryEnter(object, ref bool) - introduced in .NET 4.0

bool lockAcquired;
try
{
    Monitor.TryEnter(lockObject, ref lockAcquired);
    if (lockAcquired)
    {
        DoSomething();
    }
}
finally
{
    if (lockAcquired)
    {
        Monitor.Exit(lockObject);
    }
}

I see from the MSDN documentation on the overload taking a ref bool parameter:

If the lock was not taken because an
exception was thrown, the variable
specified for the lockTaken parameter
is false after this method ends. This
allows the program to determine, in
all cases, whether it is necessary to
release the lock.

But the documentation also states that the overload taking only the object parameter throws no exceptions other than ArgumentNullException. So it seems like if an exception were thrown in code snippet 1 above, it could only be because lockObject is null, in which case no lock was taken (and TryEnter would've returned false) anyway, so the Monitor.Exit call would not be needed.

Clearly they would not have introduced this overload for no reason. So what scenario is the Monitor.TryEnter(object, ref bool) method intended to address?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

俯瞰星空 2024-09-25 12:38:39
  1. Monitor.TryEnter 可能会成功,然后触发异步异常,例如 ThreadAbortException 或 OutOfMemoryException(在没有可见分配的情况下可能会发生)。然后锁将被占用但永远不会被释放。

请参阅:锁和异常不混合

  1. Monitor.TryEnter could succeed and then an asynchroneous exception like ThreadAbortException or OutOfMemoryException (that can happen without visible allocations) is triggered. Then the lock would be taken but never released.

See: Locks and exceptions do not mix

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文