0

以下のbuttonClickイベントが無効な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();

        }

using MyApplication.InformationProviders;アプリケーション内に Class1.cs ファイルを含む InformationProviders というフォルダーがあり、上記のボタン クリック イベントを含む MainWindow.xaml.cs ファイルに正しいステートメントを実装しました。

また、backgroundworker DoWork イベントで呼び出される Class1 クラスを次のように正しく宣言しました。

readonly Class1 _class1 = new Class1();

Class1.cs ファイルには、機能するかどうかを確認するためだけに作成されたこの小さなコードが含まれていますが、残念ながら機能しません。

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

ここで何が欠けていますか???? 私はクラスをパブリックとして宣言し、(私は信じています)プロセスを機能させるために宣言する必要があるすべてを宣言しました...

これは、バックグラウンド ワーカー プロセスが完了したことを意味する "Done" というメッセージを表示するだけです (ただし、DoWork イベントで指定されていることは何も実行していません)。

よろしくお願いします。

サイモン

4

2 に答える 2

3

マルチスレッド アプリケーションを実行する際の注意点は次のとおりです。UI にアクセスして操作を実行できるスレッドは 1 つだけです。

コードの場合、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 に答える