C# .net 2.0锁定和异常,然后重试。除了线程中止,还有其他异常吗?
今天我遇到了这样一个问题: 我使用的是.NET2.0,所以,基本上,这段代码C# .net 2.0锁定和异常,然后重试。除了线程中止,还有其他异常吗?,c#,multithreading,locking,.net-2.0,C#,Multithreading,Locking,.net 2.0,今天我遇到了这样一个问题: 我使用的是.NET2.0,所以,基本上,这段代码 lock(syncRootVar) { DoStuff(); } 将发展成这样 Monitor.Enter(syncRootVar); try { DoStuff(); } finally { Monitor.Exit(syncRootVar); } 正如Lippert在博客上所写的,在Enter调用和try finally块之间可能有一个nop操作,这是引发线程中止异常的一个潜在位置,因
lock(syncRootVar) {
DoStuff();
}
将发展成这样
Monitor.Enter(syncRootVar);
try {
DoStuff();
} finally {
Monitor.Exit(syncRootVar);
}
正如Lippert在博客上所写的,在Enter调用和try finally块之间可能有一个nop操作,这是引发线程中止异常的一个潜在位置,因此会破坏锁
关于这一点,我有两个问题:
- 是否有一种常见的方法来处理这种麻烦的情况,并且仍然清理锁对象以不影响其他线程
- 是否存在其他可能导致获取锁,但在try finally块之前引发异常的情况
try
/中获取。无法获取锁,但无法执行finally
子句
现在(也正如文章所指出的),您有一个不同的问题:如果受保护代码块中的代码处于突变状态,则异常可能导致其他代码看到部分突变状态。这可能是问题,也可能不是问题;通常情况下是这样,但当然每个特定场景都是不同的。在这种情况下,某些代码可能是安全的
•是否有一种常见的方法来处理这种麻烦的情况,并且仍然清理锁对象以不影响其他线程
对于您询问的具体情况,您可以做的两件最大的事情是:
不要中止线程。这始终是一个很好的建议,应该始终遵循。如果不中止线程,就不会出现该问题
使用最新版本的编译器。较新版本的编译器不会生成易受问题影响的代码
•是否有其他情况可能导致获取锁,但在try finally块之前引发异常
不,不适用于最新版本的编译器。甚至没有原来的情况
那么,那个令人讨厌的“部分变异”问题呢?好吧,你必须单独处理每个案例。但是,如果可能引发异常,并且可以将锁保留为部分变异状态,那么您必须添加自己的清理代码。例如:
lock(syncRootVar) {
try {
DoStuff();
} catch {
UndoStuff();
throw;
}
}