[英]In C# how can I safely exit a lock with a try catch block inside?
以下是使用try-catch塊在鎖內發生異常的示例。
int zero = 0;
int j = 10;
lock (sharedResource.SyncRoot)
{
try
{
j = j / zero;
}
catch (DivideByZeroException e)
{
// exception caught but lock not released
}
}
如何在捕獲中安全地釋放此鎖定?
它不會自動發布嗎?
從MSDN鎖定手段
System.Threading.Monitor.Enter(x);
try {
...
}
finally {
System.Threading.Monitor.Exit(x);
}
所以你不必費心。
在您超出鎖定(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.
}
證明。
.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
Jaredpar在評論中發布了一個鏈接,我認為值得一試:
http://blogs.msdn.com/ericlippert/archive/2009/03/06/locks-and-exceptions-do-not-mix.aspx
在這篇博文中,Eric Lippert評論了與鎖定C#相關的問題:
這里的問題是,如果編譯器在監視器輸入和嘗試保護區域之間生成無操作指令,則運行時可能會在監視器進入之后但在嘗試之前拋出線程中止異常。 在那種情況下,最終永遠不會運行,因此鎖泄漏,可能最終導致程序死鎖。 如果在未優化和優化的構建中這是不可能的,那將是很好的。
你的代碼非常好。 lock(sth){...}
在內部轉換為try finally
塊。
無論如何都不會這樣運行:
try
{
lock (sharedResource.SyncRoot)
{
int bad = 2 / 0;
}
}
catch (DivideByZeroException e)
{
// exception caught but lock not released
}
finally
{
//release lock
}
鎖定將在其塊的上下文退出時釋放,但是會發生這種情況。 在上面給出的代碼示例中,當控件退出最終的上下文時,鎖將自動安全地釋放。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.