我可以在锁内放一个return语句

Dupe: 在锁定程序中返回声明:内部或外部

标题有点误导。 我知道你可以做到,但我想知道性能影响。

考虑这两个代码块。 (没有error handling)

该块具有锁定之外的return

  public DownloadFile Dequeue() { DownloadFile toReturn = null; lock (QueueModifierLockObject) { toReturn = queue[0]; queue.RemoveAt(0); } return toReturn; } 

该块锁中具有return语句

  public DownloadFile Dequeue() { lock (QueueModifierLockObject) { DownloadFile toReturn = queue[0]; queue.RemoveAt(0); return toReturn; } } 

代码有什么不同吗? 我理解性能差异(如果有的话)是最小的,但我特别想知道lock释放的顺序是否会有所不同。

C#编译器会将return语句移动到为lock语句创建的try/finally之外。 您的两个示例在编译器将为它们发出的IL方面是相同的。

这是一个简单的例子,certificate:

 class Example { static Object obj = new Object(); static int Foo() { lock (obj) { Console.WriteLine("Foo"); return 1; } } static int Bar() { lock (obj) { Console.WriteLine("Bar"); } return 2; } } 

上面的代码被编译为以下代码:

 internal class Example { private static object obj; static Example() { obj = new object(); return; } public Example() { base..ctor(); return; } private static int Bar() { int CS$1$0000; object CS$2$0001; Monitor.Enter(CS$2$0001 = obj); Label_000E: try { Console.WriteLine("Bar"); goto Label_0025; } finally { Label_001D: Monitor.Exit(CS$2$0001); } Label_0025: CS$1$0000 = 2; Label_002A: return CS$1$0000; } private static int Foo() { int CS$1$0000; object CS$2$0001; Monitor.Enter(CS$2$0001 = obj); Label_000E: try { Console.WriteLine("Foo"); CS$1$0000 = 1; goto Label_0026; } finally { Label_001E: Monitor.Exit(CS$2$0001); } Label_0026: return CS$1$0000; } } 

正如您所看到的,编译器已经采用了在try/finally之外的Foo中移动return语句的库。

我相信IL会是相同的…我必须测试它才能确定,但​​是lock语句最后会在IL中生成一个try,并且返回会在堆栈帧之前触发finally(带有释放)无论如何关闭并返回给调用者,所以……

是的,但为什么不使用Dequeue?

记住锁只是简单的简写,基本上是:

  try { Monitor.Enter(QueueModifierLockObject); DownloadFile toReturn = queue.Dequeue(); return toReturn; } finally { Monitor.Exit(QueueModifierLockObject); }