Following scenario:
In an WPF application the program calls Log.Write to enqueue messages which will be written to different outputs (DB, File) in another thread. The amount of datasets written can vary from small amounts to 50000 or more entries. The user can close the application every time. To ensure all data will be written even though the user tries to close the application on Application.Exit a Log.Dispose function is called from UI Thread. The UI Thread joins the background thread to wait till all data is written. This is happening on Application.Exit.
Now it would be great to show a progress dialog during this process. The problem is, that the progress is not moving with the following code:
// Initialize
Log.CurrentInstance.DisposingProgress += new EventHandler<DisposingEventArgs>(Log_DisposingProgress)
// initialize dialog
// ...
_dialog.Show();
Log.Dispose(); // in this method data is written back, threads closed and so on
protected void SetPercentage(DisposingEventArgs e)
{
if (e.DisposingCompleted)
_dialog.Close();
_dialog.Value = e.Percentage;
}
// this function is called by a timer which checks the status of the disposing process
protected void Log_DisposingProgress(object sender, DisposingEventArgs e)
{
_dialog.Dispatcher.Invoke(new Action<DisposingEventArgs>(SetPercentage), e);
}
I guessed the problem occures because I call Log.Dipose from UI Thread. So I tried to call Log.Dispose with
new Action(Log.Dispose).BeginInvoke(null, null);
This will make the progress bar moving if I call Dispose on an event like a button click and the application is still running. If I call it from Application.Exit I have to prevent the application from closing. I try it with
new Thread(() => { while(_isDisposing) Thread.Sleep(100); }
but the progress bar is still not moving in this case.
I tried to start another UI Thread where the Progress Dialog should be displayed in, but the program will just close. Because the shutdown call will be still handled when I call Dispatcher.Run().
After longer time now, i try it again. The following code does what I wanted to achieve: