Search code examples
c#wpfautoresetevent

Dispatcher.Invoke from a new thread is locking my UI


i'm using wpf, there's a button on my ui.

when the user clicks it, i have a for loop that runs a new method, on a new thread using autoresetevent.

in that method on that new thread, i'm using a label, let's call it lblStatus. i want to update that label on this thread that's not on the ui. using wpf, i have to use Dispatcher.Invoke.

here's a sample of my code:

 Thread thread= new Thread(StartLooking);
 thread.Start();
 _waitHandle.WaitOne();

 private void StartLooking(object value)
{
 if (lblStatus.Dispatcher.Thread == Thread.CurrentThread)
        {
            lblStatus.Content = "Scanning>...";
        }
        else
        {
            lblStatus.Dispatcher.Invoke(DispatcherPriority.Background, new Action(() => lblStatus.Content = "Scanning>>>>>")); 
        }
 _waitHandle.Set();
}

the program just stops here. it doesn't change the content of the label, it returns to my ui, but blocks it.
i've tried

lblStatus.Dispatcher.Invoke(DispatcherPriority.Normal, new LblStatusThreadCheck(lblStatusThreadCheck), "Scanning...");

as well, but that isn't working also. any ideas?


Solution

  • The problem is that you're making it impossible for this to execute, since you're using Invoke.

    Dispatcher.Invoke will not return until the UI thread processes. However, you've blocked the UI thread by calling _waitHandle.WaitOne();, and don't set the wait handle until AFTER this processes. The two effectively cause a dead lock.

    If you switch this to use BeginInvoke instead, the UI will queue the element, the wait handle will set, THEN the label will update. It will work and not block, however.