I’m creating a WPF MVVM application. I have a long process that I want to run in another thread whilst displaying a busy indicator to the user. The problem I have is as follows:
The IsBusy property of the BusyIndicator control is bound to the IsBusy public property of my view model which implements the INotifyPropertyChanged interface. If I run the code below with the Join then the user interface doesn’t show the busy indicator as the main UI thread is waiting for the thread “t” to finish. If I remove the join then the Windows Form which is hosting the WPF closes too early. I know that accessing Windows Forms across threads is a big no no but as all I want to do is close the Form I figure the most simple solution is to move _hostForm.Close() to the end of the “DoLongProcess” method. Of course if I do that I get a cross threading exception. Can you please suggest the best approach to take in this situation?
<extToolkit:BusyIndicator IsBusy="{Binding Path=IsBusy}" >
<!-- Some controls here -->
</extToolkit:BusyIndicator>
private void DoSomethingInteresting() {
// Set the IsBusy property to true which fires the
// notify property changed event
IsBusy = true;
// Do something that takes a long time
Thread t = new Thread(DoLongProcess);
t.Start();
t.Join();
// We're done. Close the Windows Form
IsBusy = false;
_hostForm.Close();
}
The best thing to do in this situation, is before you actually invoke the closing of the form, you notify all your systems you are going to close, which will give you the opportunity to run any process at the end. When you are then finished and want to close the form from the other thread, you will need to call it on the UI thread using:
It might be better, if you are likely to always close the form from another thread, to actually create a thread-safe version of the close method; i.e.:
Using this sort of approach, you can continue to update the form and it’s UI while running asynchronous operations, then invoke the shutdown and cleanup when your done.