首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Monitor.Exit()上的SynchronizationLockException?

Monitor.Exit()上的SynchronizationLockException?
EN

Stack Overflow用户
提问于 2013-06-14 22:19:42
回答 3查看 3.3K关注 0票数 2

我使用Monitor类来管理临界区。但有时我会遇到SynchronizationLockException,并显示以下消息

代码语言:javascript
运行
复制
An unhandled exception of type 'System.Threading.SynchronizationLockException' occurred in ManagedType.dll
Additional information: Object synchronization method was called from an unsynchronized block of code.

我的代码如下

代码语言:javascript
运行
复制
Object^ lockObj = gcnew Object(); //Global variable
bool GetValue()
{
    try
    {
        Monitor::Enter(lockObj);
        return this.value;
    }
    finally
    {
        Monitor::Exit(lockObj);
    }
}

Monitor::Exit(lockObj)调用时引发的SynchronizationLockException

我已经在这个论坛和互联网上搜索过了,但大多数话题包括MSDN都说“当你试图在Monitor.Enter()和Monitor.Exit()中使用值类型变量而不是引用类型时,会抛出这个异常”。

但在我的例子中,我使用的是lockObj,它是引用对象。所以我不知道为什么它会抛出这个异常。有人能帮我吗?

非常感谢,

T&T组!

EN

回答 3

Stack Overflow用户

发布于 2013-06-14 23:19:34

发布的代码根本就是错误的。::Enter()调用必须出现在{}块的外部。

故障模式非常糟糕且无法诊断。如果Enter()调用出于任何原因抛出异常,那么finally{}块中的Exit()调用将崩溃,并记录异常,因为从未进入监视器。它是不可诊断的,因为该异常替换了Enter()方法抛出的异常,您既看不到它,也捕捉不到原始异常。所以你不知道为什么这段代码会失败,也不能修复这个问题。

将Enter调用移到try块的上方。这仍然不能解决你的代码崩溃的问题,但至少你现在有了一些关于真正出错的信息。

顺便说一句,请注意.NET 4.0中添加的Monitor::Enter()重载,旨在解决此类问题。它需要一个额外的bool%参数,当Enter()成功时,该参数将被设置为true,这样您就知道调用Exit()是安全的。

票数 5
EN

Stack Overflow用户

发布于 2013-06-14 23:37:22

@Hans是部分正确的。使用接受引用布尔值的Monitor.Enter重载。此重载始终设置传递给ref参数lockTaken的变量的值,即使该方法抛出异常,因此该变量的值是测试是否必须释放锁的可靠方法。但是一定要把Monitor.Enter调用放在try块中。您的代码应该类似于

代码语言:javascript
运行
复制
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);
    }
}
票数 3
EN

Stack Overflow用户

发布于 2015-04-18 04:18:40

好了,我刚刚处理了这个问题。我相信这会解决你的问题。尝试将对象设置为NULL;它对我有效。

代码语言:javascript
运行
复制
Object^ lockObj=NULL;

Monitor::Enter(lockObj);
try
{
     return this.value;
}
 finally
 {
     Monitor::Exit(lockObj);
 }
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17110673

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档