Search code examples
c#wpfmultithreadingdispatchersta

WPF Recreation window in different STA thread


I need to create window with loading gif when my main window is rendering. I have read some articles and make a decision that for this purposes i need to create new thread. I did it like in this article

As a result I have something like that:

LoadingDialog _loadingDlg;
Thread loadingThread;

public void ShowLoading()
{
    loadingThread = new Thread(new ThreadStart(loadingThreadWork));
    loadingThread.SetApartmentState(ApartmentState.STA);
    loadingThread.Start();
}

private void loadingThreadWork()
{
    _loadingDlg = new LoadingDialog();
    _loadingDlg.Show();
    System.Windows.Threading.Dispatcher.Run();
}

public void HideLoading()
{
    _loadingDlg.Dispatcher.InvokeShutdown();
}

First time when I call ShowLoading() and then HideLoading() everything works like I want. But when I call ShowLoading() at the second time I get an exception at

_loadingDlg.Show();

with message The calling thread cannot access this object because a different thread owns it.

How can this be? _loadingDlg is created in the previous line, and in the same thread.


Solution

  • In the loadingThreadWork you're creating the control, before the first run it's a null, so in first time you succeed. However, you're creating the dialog in a different thread, which is marked as an owner for the control.

    At the next time you're calling the loadingThreadWork, control isn't null, and ant change for it from a different thread (and it is a different thread, because you're creating it again) leads to the exception you've got.

    As you're using WPF, you probably should switch from threads to async operations, which are much more readable, supportable and predictable than your current solution.