Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Differing behavior when starting a thread: ParameterizedThreadStart vs. Anonymous Delegate. Why does it matter?

When I run the code below the output is "DelegateDisplayIt", typically repeated 1-4 times. I've run this code probably 100 times, and not once has the output ever been "ParameterizedDisplayIt". So it seems the manner in which the thread is created and subsequently started affects how the parameter is passed. When creating a new thread with an anonymous delegate the parameter is a reference back to the original variable, but when created with a ParameterizedThreadStart delegate the parameter is an entirely new object? Does my assumption seem correct? If so, this seems an odd side affect of the thread constructor, no?

static void Main()
{
    for (int i = 0; i < 10; i++)
    {
        bool flag = false;

        new Thread(delegate() { DelegateDisplayIt(flag); }).Start();

        var parameterizedThread = new Thread(ParameterizedDisplayIt);
        parameterizedThread.Start(flag);

        flag = true;
    }

    Console.ReadKey();
}

private static void DelegateDisplayIt(object flag)
{
    if ((bool)flag)
        Console.WriteLine("DelegateDisplayIt");
}

private static void ParameterizedDisplayIt(object flag)
{
    if ((bool)flag)
        Console.WriteLine("ParameterizedDisplayIt");
}
like image 512
Matthew Sposato Avatar asked Dec 17 '09 18:12

Matthew Sposato


1 Answers

Your assumption is correct. The statement parameterizedThread.Start(flag) copies the flag variable at the time of the call.

By contrast, the anonymous delegate captures the original variable in a closure. The variable isn't copied until the delegate executes the DelegateDisplayIt method. At that point, the value may be true or false, depending on where the original thread is in the calling loop.

like image 151
Jeff Sternal Avatar answered Sep 30 '22 17:09

Jeff Sternal