Search code examples
c#winformsthreadpoolautoresetevent

C# main thread is blocked by second thread using signaling?


GetFiles creates the second thread which calls CopyFiles, I am just trying to fill the listbox with the file name each time a file is copied, but once code hits line:

listBox1.Invoke((MethodInvoker)delegate { PrintProgress(i.ToString()); }, new object[] { }); 

main thread gets blocked, any ideas?

void GetFiles()
{
    AutoResetEvent autoEvent = new AutoResetEvent(false);
    ThreadPool.QueueUserWorkItem(new WaitCallback(CopyFiles),autoEvent);

    //some unrelated code

    autoEvent.WaitOne();
}

private void CopyFiles(object stateInfo)
{
    for (int i = 0; i < 10; i++)
    {
        //SetControlPropertyValue(listBox1, i.ToString());       
        listBox1.Invoke((MethodInvoker)delegate { PrintProgress(i.ToString()); }, new object[] { });
        Thread.Sleep(1000);
    }

    // Signal that this thread is finished.
    ((AutoResetEvent)stateInfo).Set();     
}

private void PrintProgress(string number)
{
    listBox1.Items.Add(number);
}

Solution

  • Your main thread hanged because you are calling the GetFiles() from it. so you have a dead lock, here is a scenario:

    The main thread will block at line autoEvent.WaitOne(); waiting for a signal to proceed, but it will never receive that signal because the signal is depending on executing a code on the main thread "listBox1.Items.Add(number);" and the last one will blocked waiting for autoEvent.WaitOne() to finish. a dead lock.

    To fix that run the GetFiles() method from another thread rather than the main thread, so:

    ThreadPool.QueueUserWorkItem(new WaitCallback((_) => { GetFiles(); }), null);