后台工作人员拒绝为其他班级做任何事情

本文关键字:任何事 其他 工作人员 拒绝 后台 | 更新日期: 2023-09-27 18:26:22

我有一个带有以下按钮的WPF C#项目点击事件无效:

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();
        }

我在应用程序中有一个名为InformationProviders的文件夹,其中包含Class1.cs文件,并且我在MainWindow.xaml.cs文件中实现了正确的using MyApplication.InformationProviders;语句,该文件包含上面的按钮单击事件。

我还正确地声明了Class1类,然后在backgroundworkerDoWork事件中调用它:

readonly Class1 _class1 = new Class1();

Class1.cs文件包含这个小代码,只是为了看看它是否有效,不幸的是它没有:

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

我在这里错过了什么????我将类声明为public,并且(我相信)声明了使流程工作所需的所有内容。。。

它所做的只是显示一条消息,上面写着"完成",这意味着它已经完成了后台工作程序(尽管它根本没有做DoWork事件中所说的任何事情)。所以,启动工作程序并立即认为它已经完成。

问候和感谢,

Simon

后台工作人员拒绝为其他班级做任何事情

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

对于您的代码,其后台操作中的BackgroudWorker会尝试使用MessageBox显示消息。这不起作用——它不会在UI线程上被"激发"!

如果您绝对必须从BackgroundWorker内部执行UI操作(这是不应该做的——这就是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);
        };

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