Can I put a return statement inside a lock

后端 未结 3 1487
温柔的废话
温柔的废话 2021-01-01 20:07

Dupe: return statement in a lock procedure: inside or outside

The title is a little misleading. I know that you can do it, but I\'m wondering about

相关标签:
3条回答
  • 2021-01-01 20:42

    Yes, but why not use Dequeue?

    Remember lock is simply shorthand for essentially something along the lines of:

            try
            {
                Monitor.Enter(QueueModifierLockObject);
    
                DownloadFile toReturn = queue.Dequeue();         
    
                return toReturn;
            }
            finally
            {
                Monitor.Exit(QueueModifierLockObject);
            }
    
    0 讨论(0)
  • 2021-01-01 20:44

    The C# compiler will move the return statement outside of the try/finally that is created for the lock statement. Both of your examples are identical in terms of the IL that the compiler will emit for them.

    Here is a simple example proving that:

    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;
        }
    }
    

    The code above gets compiled to the following:

    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;
            }
    }
    

    As you can see, the compiler has taken the libery of moving the return statement in Foo outside of the try/finally.

    0 讨论(0)
  • 2021-01-01 20:50

    I believe the IL would be identical... I'd have to test it to be fer sure, but the lock statement generates a try finally in the IL, and the return would trigger the finally (with the release) BEFORE the stack frame closes and returns to the caller anyway, so...

    0 讨论(0)
提交回复
热议问题