在BackgroundWorker运行时显示模态窗口,而不会出现STA / MTA问题

我正在研究WPF应用程序。 我有一个耗时的方法,我想通过BackgroundWorker运行异步。 当该方法运行时,我想显示一个模态“Please Wait …”对话框窗口,该窗口必须在BackgroundWorker完成时自动关闭。

我目前对BackgroundWorker或任何multithreading编程的经验很少。

下面的代码当前导致InvalidOperationException ,消息“调用线程必须是STA,因为许多UI组件需要这个”。

请告诉我如何实现我想要实现的目标,以及额外的布朗尼点,如果你能帮我理解出了什么问题。

非常感谢!

编辑只是澄清 – 想法是主线程启动BackgroundWorker ,然后显示modal dialog。 当工人完成时,它会关闭modal dialog。 当模式对话框关闭时,主线程继续。

 public class ImageResizer { private BackgroundWorker worker; private MemoryStream ImageData { get; set; } // incoming data private public MemoryStream ResizedImageData { get; private set; } // resulting data private Dialogs.WorkInProgressDialog ProgressDialog; // Public interface, called by using class: public MemoryStream ReduceImageSize(MemoryStream imageData) { // injected data: this.ImageData = imageData; // init progress dialog window: ProgressDialog = new Dialogs.WorkInProgressDialog(); // Start background worker that asyncronously does work worker = new BackgroundWorker(); worker.DoWork += new DoWorkEventHandler(worker_DoWork); worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted); worker.RunWorkerAsync(); // Show progress dialog. Dialog is MODAL, and must only be closed when resizing is complete ProgressDialog.ShowDialog(); // THIS LINE CAUSES THE INVALID OPERATION EXCEPTION // This thread will only continue when ProgressDialog is closed. // Return result return ResizedImageData; } private void worker_DoWork(object sender, DoWorkEventArgs e) { // Call time consuming method ResizedImageData = ReduceImageSize_ActualWork(); } // The actual work method, called by worker_DoWork private MemoryStream ReduceImageSize_ActualWork() { // Lots of code that resizes this.ImageData and assigns it to this.ResizedImageData } private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { // Async work completed - close progress dialog ProgressDialog.Close(); } } 

您无法从BackgroundWorker调用ShowDialog。 您必须使用Dispatcher来请求UI线程执行它:

  this.Dispatcher.BeginInvoke(new Action(() => ProgressDialog.ShowDialog())); 

BackgroundWorker的“Completed”事件在UI线程中执行,因此这部分应该没问题。