0

I have a WPF C# projects with the below buttonClick event void:

public void ButtonClick(object sender, RoutedEventArgs e)
        {
            _worker.WorkerReportsProgress = true;

            _worker.DoWork += (o, ea) =>
                                  {
                                      try
                                      {
                                          _class1.hithere();
                                      }
                                      catch (Exception exception)
                                      {
                                          MessageBox.Show(exception.Message);
                                      }
                                  };
            _worker.ProgressChanged += (o, ea) =>
                                           {

                                           };
            _worker.RunWorkerCompleted += (o, ea) =>
                                              {
                                                  MessageBox.Show("Done");
                                              };

            _worker.RunWorkerAsync();

        }

I have a folder in the application called InformationProviders than contains the Class1.cs file and I have implemented the correct using MyApplication.InformationProviders; statement in the MainWindow.xaml.cs file that contains the button click event above.

I have also declared the Class1 class that is then called upon in the backgroundworker DoWork event correctly as such:

readonly Class1 _class1 = new Class1();

The Class1.cs file contains this little code made just to see if it worked and it doesn't unfortunately:

public class Class1
    {
        public void hithere()
        {
            MessageBox.Show("Hi, I'm working.");
        }
    }

What am I missing here???? I declared the class as public and (I believe) declared all that needed to be declared to make the process work...

All it does is display a message saying "Done", meaning it has completed the backgroundworker process (even though it did not do anything at all that was stated in the DoWork event. So pretty much, launching the worker and immediately considering it finished.

Regards and thanks,

Simon

4

2 回答 2

3

这是运行多线程应用程序的棘手之处:只有一个线程可以访问 UI 并对其执行操作。

对于您的代码,BackgroudWorker它的后台操作会尝试使用MessageBox. 这是行不通的——它没有在 UI 线程上被“解雇”!

如果您绝对必须从内部执行 UI 操作BackgroundWorker(您不应该这样做 - 这就是ProgressChanged事件的用途),那么您可以使用一个Dispatcher类。

这是一个简短的示例:

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        BackgroundWorker bw = new BackgroundWorker();
        bw.DoWork += (s, a) =>
        {
            this.Dispatcher.Invoke(new Action(() => MessageBox.Show("doing stuff")));
        };
        bw.RunWorkerCompleted += (s, a) =>
        {
            MessageBox.Show("done");
        };
        bw.RunWorkerAsync();
    }

另一个有趣的事实是,如果你使用Dispatcher.Invoke(如上所述),那么“doing stuff”将首先出现,如果你使用,Dispatcher.BeginInvoke那么“done”将首先出现,因为其他操作将在 UI 线程上排队。

这是使用 的“政治正确”方式BackgroundWorker

        bw.WorkerReportsProgress = true;
        bw.DoWork += (s, a) =>
        {
            bw.ReportProgress(0, "doing stuff");
        };
        bw.ProgressChanged += (s, a) =>
        {
            MessageBox.Show(a.UserState as String);
        };
于 2013-08-03T17:06:14.980 回答
0

我发现了问题,我正在使用 MessageBox 的 Xceed.WPF.toolkit 版本,它只是拒绝在 backgroundWorker 中显示该 UI 元素。感谢您的帮助,尽管它为我指明了正确的方向。希望这会帮助其他人

于 2013-08-03T17:20:45.183 回答