Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .net 2.0锁定和异常,然后重试。除了线程中止,还有其他异常吗?_C#_Multithreading_Locking_.net 2.0 - Fatal编程技术网

C# .net 2.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操作,这是引发线程中止异常的一个潜在位置,因

今天我遇到了这样一个问题:

我使用的是.NET2.0,所以,基本上,这段代码

lock(syncRootVar) {
    DoStuff();
}
将发展成这样

Monitor.Enter(syncRootVar);
try {
    DoStuff();
} finally {
    Monitor.Exit(syncRootVar);
}
正如Lippert在博客上所写的,在Enter调用和try finally块之间可能有一个nop操作,这是引发线程中止异常的一个潜在位置,因此会破坏锁

关于这一点,我有两个问题:

  • 是否有一种常见的方法来处理这种麻烦的情况,并且仍然清理锁对象以不影响其他线程
  • 是否存在其他可能导致获取锁,但在try finally块之前引发异常的情况

正如文章所指出的,您似乎关心的问题不再是一个问题。C#编译器已被更改(可能Roslyn会保留更改),因此锁将在
try
/
中获取。无法获取锁,但无法执行
finally
子句

现在(也正如文章所指出的),您有一个不同的问题:如果受保护代码块中的代码处于突变状态,则异常可能导致其他代码看到部分突变状态。这可能是问题,也可能不是问题;通常情况下是这样,但当然每个特定场景都是不同的。在这种情况下,某些代码可能是安全的


•是否有一种常见的方法来处理这种麻烦的情况,并且仍然清理锁对象以不影响其他线程

对于您询问的具体情况,您可以做的两件最大的事情是:

  • 不要中止线程。这始终是一个很好的建议,应该始终遵循。如果不中止线程,就不会出现该问题
  • 使用最新版本的编译器。较新版本的编译器不会生成易受问题影响的代码
  • •是否有其他情况可能导致获取锁,但在try finally块之前引发异常

    不,不适用于最新版本的编译器。甚至没有原来的情况


    那么,那个令人讨厌的“部分变异”问题呢?好吧,你必须单独处理每个案例。但是,如果可能引发异常,并且可以将锁保留为部分变异状态,那么您必须添加自己的清理代码。例如:

    lock(syncRootVar) {
        try {
            DoStuff();
        } catch {
            UndoStuff();
            throw;
        }    
    }