当前位置:  开发笔记 > 编程语言 > 正文

在C#中,如何使用try catch块安全地退出锁?

如何解决《在C#中,如何使用trycatch块安全地退出锁?》经验,为你挑选了4个好方法。

以下是使用try-catch块在锁内发生异常的示例.

int zero = 0;
int j = 10;

lock (sharedResource.SyncRoot)
{
    try
    {
        j = j / zero;
    }
    catch (DivideByZeroException e)
    {
        // exception caught but lock not released
    }
}

如何在捕获中安全地释放此锁定?



1> Mykola Golub..:

它不会自动发布吗?

从MSDN锁定手段

System.Threading.Monitor.Enter(x);
try {
   ...
}
finally {
   System.Threading.Monitor.Exit(x);
}

所以你不必费心.


+1,这是你用CLR 2.0做的最好的,但它实际上并非万无一失.http://blogs.msdn.com/ericlippert/archive/2009/03/06/locks-and-exceptions-do-not-mix.aspx

2> Michael..:

在您超出锁定(sharedResource.SyncRoot)块的范围之前,不会释放锁定. lock (sharedResource.SyncRoot) {}基本上与:

Monitor.Enter(sharedResource.SyncRoot);
try
{
}
finally
{
    Monitor.Exit(sharedResource.SyncRoot);
}

如果您想要更多控制,您可以自己进入/退出,或者只是将锁定重新锁定到您想要的位置,例如:

try
{
    lock(sharedResource.SyncRoot)
    {
        int bad = 2 / 0;
    }
}
catch (DivideByZeroException e)
{
   // Lock released by this point.
}



3> annakata..:

证明.

.method public hidebysig instance void  test(int32 i) cil managed
{
  // Code size       43 (0x2b)
  .maxstack  2
  .locals init ([0] int32 bad,
           [1] class [mscorlib]System.DivideByZeroException e,
           [2] object CS$2$0000)
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  ldfld      object WebApplication1.myclass::mutex
  IL_0007:  dup
  IL_0008:  stloc.2
  IL_0009:  call       void [mscorlib]System.Threading.Monitor::Enter(object)
  IL_000e:  nop
  .try
  {
    IL_000f:  nop
    .try
    {
      IL_0010:  nop
      IL_0011:  ldc.i4.2
      IL_0012:  ldarg.1
      IL_0013:  div
      IL_0014:  stloc.0
      IL_0015:  nop
      IL_0016:  leave.s    IL_001d
    }  // end .try
    catch [mscorlib]System.DivideByZeroException 
    {
      IL_0018:  stloc.1
      IL_0019:  nop
      IL_001a:  nop
      IL_001b:  leave.s    IL_001d
    }  // end handler
    IL_001d:  nop
    IL_001e:  nop
    IL_001f:  leave.s    IL_0029
  }  // end .try
  finally
  {
    IL_0021:  ldloc.2
    IL_0022:  call       void [mscorlib]System.Threading.Monitor::Exit(object)
    IL_0027:  nop
    IL_0028:  endfinally
  }  // end handler
  IL_0029:  nop
  IL_002a:  ret
} // end of method myclass::test



4> Justin Tanne..:

Jaredpar在评论中发布了一个链接,我认为值得一试:

http://blogs.msdn.com/ericlippert/archive/2009/03/06/locks-and-exceptions-do-not-mix.aspx

在这篇博文中,Eric Lippert评论了与锁定C#相关的问题:

这里的问题是,如果编译器在监视器输入和尝试保护区域之间生成无操作指令,则运行时可能会在监视器进入之后但在尝试之前抛出线程中止异常.在那种情况下,最终永远不会运行,因此锁泄漏,可能最终导致程序死锁.如果在未优化和优化的构建中这是不可能的,那将是很好的.

推荐阅读
谢谢巷议
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有