The program hangs on Dispatcher.Run () C #

I am using this code to run the ProgressBar on a separate thread.

ProgresBarForm viewer = new ProgressBarForm("Wait");    
Thread viewerThread = new Thread(delegate()
    {
        viewer = new ProgressBarForm("Wait");
        viewer.Show();
        System.Windows.Threading.Dispatcher.Run();
    });

viewerThread.SetApartmentState(ApartmentState.STA); // needs to be STA or throws exception
viewerThread.Start();

      

Then I do a long operation, and when I finish, I call this code:

viewer.BeginInvoke(new Action(() => window.Close()));

      

and it works very well, but when I close the window the debugger doesn't stop. In VS 2012 I click the Split All button and it happens that the program hangs on the line

System.Windows.Threading.Dispatcher.Run();

      

How can I close this dispatcher to exit my program?

Thanks for all the answers.

+3


source to share


2 answers


   viewer.BeginInvoke(new Action(() => window.Close()));

      

This is not enough to stop the dispatcher. Your "viewer" is a Winforms form, not a WPF window. Thus, the normal shutdown mechanism cannot work. You have to help and also tell the dispatcher to exit:

   viewer.BeginInvoke(new Action(() => {
       System.Windows.Threading.Dispatcher.CurrentDispatcher.InvokeShutdown();
       viewer.Close();
   }));

      



Beware of race, the user might close your WPF window before you get a chance to call this code. DoEvents () visions suffer. Therefore, you should probably also set the Thread IsBackground property to true. And beware of problems displaying the user interface in the workflow, you must carefully handle your "progress" so that it does not use any dangerous controls in the toolbar. Those using the SystemEvents class. Or you can debug a dead end like this .

It works better and more reliably forever if you don't let your UI work do the hard work. Let it only care about the UI, do the heavy lifting in the working thread.

+4


source


Because your thread is the foreground thread, which is enough to keep your process running.

Make a background thread by setting viewerThread.IsBackGround = true

so it can't save your process.



Or inside the callback, when you close the window, just call Dispatcher.InvokeShutdown

after the window is closed.

+3


source







All Articles