以下是使用try-catch块在锁内发生异常的示例.
int zero = 0;
int j = 10;
lock (sharedResource.SyncRoot)
{
try
{
j = j / zero;
}
catch (DivideByZeroException e)
{
// exception caught but lock not released
}
}
Run Code Online (Sandbox Code Playgroud)
如何在捕获中安全地释放此锁定?
Myk*_*yev 36
它不会自动发布吗?
从MSDN锁定手段
System.Threading.Monitor.Enter(x);
try {
...
}
finally {
System.Threading.Monitor.Exit(x);
}
Run Code Online (Sandbox Code Playgroud)
所以你不必费心.
Mic*_*ael 13
在您超出锁定(sharedResource.SyncRoot)块的范围之前,不会释放锁定. lock (sharedResource.SyncRoot) {}基本上与:
Monitor.Enter(sharedResource.SyncRoot);
try
{
}
finally
{
Monitor.Exit(sharedResource.SyncRoot);
}
Run Code Online (Sandbox Code Playgroud)
如果您想要更多控制,您可以自己进入/退出,或者只是将锁定重新锁定到您想要的位置,例如:
try
{
lock(sharedResource.SyncRoot)
{
int bad = 2 / 0;
}
}
catch (DivideByZeroException e)
{
// Lock released by this point.
}
Run Code Online (Sandbox Code Playgroud)
证明.
.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
Run Code Online (Sandbox Code Playgroud)
Jaredpar在评论中发布了一个链接,我认为值得一试:
http://blogs.msdn.com/ericlippert/archive/2009/03/06/locks-and-exceptions-do-not-mix.aspx
在这篇博文中,Eric Lippert评论了与锁定C#相关的问题:
这里的问题是,如果编译器在监视器输入和尝试保护区域之间生成无操作指令,则运行时可能会在监视器进入之后但在尝试之前抛出线程中止异常.在那种情况下,最终永远不会运行,因此锁泄漏,可能最终导致程序死锁.如果在未优化和优化的构建中这是不可能的,那将是很好的.
| 归档时间: |
|
| 查看次数: |
18707 次 |
| 最近记录: |