What is this C# code usage concept called? And how does it work?

时间:2015-07-28 15:42:38

标签: c# multithreading task-parallel-library threadpool

I was looking at an MSDN about RegisterWaitForSingleObject HERE and found this usage in the example -

    ti.Handle = ThreadPool.RegisterWaitForSingleObject(
            ev,
            new WaitOrTimerCallback(WaitProc),
            ti,
            1000,
            false
        );

Where WaitProc is a method -

    public static void WaitProc(object state, bool timedOut)
    {
     //Code
    }

I also found examples where the same by replacing WaitProc method to something similar to this -

    ti.Handle = ThreadPool.RegisterWaitForSingleObject(
            ev,
            (state, timedOut) => {
            //code blah blah
            //manipulate state
            //manipulate timedOut
            }
            ti,
            1000,
            false
        );

Here I'm assuming the method RegisterWaitForSingleObject expects a WaitOrTimerCallback method, and compiler understand this and considers (state, timedOut) as the method, and hence the variables can be used within the call itself.

What is this concept called?

And how does it work?

1 个答案:

答案 0 :(得分:4)

What is this concept called?

And how does it work?

It is called a Lambda Expression. The compiler takes the expression and translates it into a named method for you, while saving you the trouble of actually defining a named method that matches the delegates signature each time.

Using TryRoslyn, this is what your delegate compiles down to (on the new Roslyn compiler):

private sealed class <>c
{
    public static readonly C.<>c <>9;
    public static WaitOrTimerCallback <>9__0_0;
    static <>c()
    {
        // Note: this type is marked as 'beforefieldinit'.
        C.<>c.<>9 = new C.<>c();
    }
    internal void <M>b__0_0(object state, bool timedOut)
    {
    }
}

public void M()
{
    Mutex mutex = new Mutex();
    WaitHandle arg_2E_0 = mutex;
    WaitOrTimerCallback arg_2E_1;
    if (arg_2E_1 = C.<>c.<>9__0_0 == null)
    {
        arg_2E_1 = C.<>c.<>9__0_0 = new WaitOrTimerCallback(C.<>c.<>9.<M>b__0_0);
    }
    RegisteredWaitHandle registeredWaitHandle = 
        ThreadPool.RegisterWaitForSingleObject(arg_2E_0, arg_2E_1, null, 1000, false);
}