.net 2.0 锁定和 try-finally 之前的异常。除了线程中止之外还有其他异常吗?
.net 2.0 lock and exceptions before the try-finally. Are there any other exceptions besides thread abort?
今天我 运行 进入了这个:
https://blogs.msdn.microsoft.com/ericlippert/2009/03/06/locks-and-exceptions-do-not-mix/
我使用的是 .net 2.0,所以,基本上,这段代码
lock(syncRootVar) {
DoStuff();
}
会展开成这样
Monitor.Enter(syncRootVar);
try {
DoStuff();
} finally {
Monitor.Exit(syncRootVar);
}
正如 Lippert 在博客上所写的那样,在 Enter 调用和 try-finally 块之间可能存在 nop 操作,这是引发线程中止异常并因此弄乱锁的潜在位置。
我有两个问题:
- 有没有一种通用的方法来处理这种麻烦的情况,并且仍然清理锁对象以便不影响其他线程?
- 是否有其他情况可能导致获取锁,但在 try-finally 块之前引发异常?
正如文章所指出的,您似乎关心的问题已不再是问题。 C# 编译器已更改(并且 Roslyn 可能会保留更改)以便在 try
/finally
内获取锁。无法获取锁但无法执行finally
子句。
现在(同样如文章所指出的)您遇到了一个不同的问题:如果受保护代码块中的代码处于变异状态,则异常可能会导致其他代码看到 partially-mutated 状态。这可能是也可能不是问题;通常是这样,但当然每个特定场景都不同。在这种情况下,某些代码可能是安全的。
• Is there a common way of handling this troublesome situation and still clean up the lock object in order to not affect other threads?
对于您询问的具体情况,您可以做的最重要的两件事是:
- 不要中止线程。这始终是个好建议,应始终遵循。如果你不中止一个线程,你就不会有那个问题。
- 使用最新版本的编译器。较新版本的编译器不会生成易受此问题影响的代码。
• Are there other situations that might result in the lock being acquired, but exceptions raising before the try-finally block?
不,不是最新版本的编译器。连原来的情况都没有
现在那个讨厌的 "partially-mutated" 问题怎么办?好吧,您必须单独处理每个案例。但是,如果可能会抛出异常,并且可能会保留 partially-mutated 状态的锁,那么您将必须添加自己的 clean-up 代码。例如:
lock(syncRootVar) {
try {
DoStuff();
} catch {
UndoStuff();
throw;
}
}
今天我 运行 进入了这个: https://blogs.msdn.microsoft.com/ericlippert/2009/03/06/locks-and-exceptions-do-not-mix/
我使用的是 .net 2.0,所以,基本上,这段代码
lock(syncRootVar) {
DoStuff();
}
会展开成这样
Monitor.Enter(syncRootVar);
try {
DoStuff();
} finally {
Monitor.Exit(syncRootVar);
}
正如 Lippert 在博客上所写的那样,在 Enter 调用和 try-finally 块之间可能存在 nop 操作,这是引发线程中止异常并因此弄乱锁的潜在位置。
我有两个问题:
- 有没有一种通用的方法来处理这种麻烦的情况,并且仍然清理锁对象以便不影响其他线程?
- 是否有其他情况可能导致获取锁,但在 try-finally 块之前引发异常?
正如文章所指出的,您似乎关心的问题已不再是问题。 C# 编译器已更改(并且 Roslyn 可能会保留更改)以便在 try
/finally
内获取锁。无法获取锁但无法执行finally
子句。
现在(同样如文章所指出的)您遇到了一个不同的问题:如果受保护代码块中的代码处于变异状态,则异常可能会导致其他代码看到 partially-mutated 状态。这可能是也可能不是问题;通常是这样,但当然每个特定场景都不同。在这种情况下,某些代码可能是安全的。
• Is there a common way of handling this troublesome situation and still clean up the lock object in order to not affect other threads?
对于您询问的具体情况,您可以做的最重要的两件事是:
- 不要中止线程。这始终是个好建议,应始终遵循。如果你不中止一个线程,你就不会有那个问题。
- 使用最新版本的编译器。较新版本的编译器不会生成易受此问题影响的代码。
• Are there other situations that might result in the lock being acquired, but exceptions raising before the try-finally block?
不,不是最新版本的编译器。连原来的情况都没有
现在那个讨厌的 "partially-mutated" 问题怎么办?好吧,您必须单独处理每个案例。但是,如果可能会抛出异常,并且可能会保留 partially-mutated 状态的锁,那么您将必须添加自己的 clean-up 代码。例如:
lock(syncRootVar) {
try {
DoStuff();
} catch {
UndoStuff();
throw;
}
}