0

多くのアプリケーションと同様に、アプリケーションが長時間の計算を行っているときにステータス テキストを更新したいと考えています。Dispatcher と BackgroundWorker に関する記事を読みました。UIスレッドで更新が行われることを確認する必要があることはわかっています。私の最初の試みは:

MyView.UpdateStatus( "Please wait" );
LongComputation();
MyView.UpdateStatus( "Ready" );

(私が思うに) LongComputation がステータスの更新を妨げているため、これは機能しません。

だから私はこれをやろうとしました:

BackgroundWorker worker = new BackgroundWorker();
MyView.UpdateStatus( "Please wait");
worker.DoWork += delegate(object s, DoWorkEventArgs args)
{
    LongComputation();
}
worker.RunWorkerAsync();
MyView.UpdateStatus( "Ready" );

余分なスレッドが UpdateStatus にステータス テキストを更新する機会を与えることを願っていました。どちらも機能しません。その理由の 1 つは、LongComputation の結果が Windows フォームに表示されることです。LongComputation を BackgroundWorker 内に配置するとすぐに、結果が表示されません。

そこで、フロー コードを使用して 3 回目の試行を行いました。

BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += delegate(object s, DoWorkEventArgs args)
{
    Dispatcher.Invoke(((Action)(() => Status.Text = args.Argument as string)));
};

worker.RunWorkerAsync(newStatus);

更新を別のスレッドに入れるとうまくいくことを望んでいました。しかし、そうではありませんでした。

ステータスが正しいプログラムの状態を反映していることを確認するにはどうすればよいですか?

4

2 に答える 2

1

BackgroundWorker は、RunWorkerCompleted および ReportProgress イベントを使用して、メイン スレッドと通信します。RunWorkerCompleted は、バックグラウンド作業が完了するとすぐに UI スレッドで実行されるため、必要なことを行う必要があります。

        BackgroundWorker worker = new BackgroundWorker();

        worker.DoWork += delegate(object s, DoWorkEventArgs args)
        {
            LongComputation();
        };

        // RunWorkerCompleted will fire on the UI thread when the background process is complete
        worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
        {
            if (args.Error != null)
            {
                // an exception occurred on the background process, do some error handling
            }

            MyView.UpdateStatus("Ready");
        };

        MyView.UpdateStatus("Please wait");
        worker.RunWorkerAsync();

さらに、RunWorkerCompleted を使用して、DoWorkerEventArgs の Result プロパティを使用して結果をメイン スレッドにマーシャリングすることができます。

        worker.DoWork += delegate(object s, DoWorkEventArgs args)
        {
            args.Result = LongComputation();
        };

        worker.rep

        // RunWorkerCompleted will fire on the UI thread when the background process is complete
        worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
        {
            if (args.Error != null)
            {
                // an exception occurred on the background process, do some error handling
            }

            var result = args.Result;

            // do something on the UI with your result

            MyView.UpdateStatus("Ready");
        };

最後に、ReportProgress イベントを使用して、バックグラウンド プロセスの論理的なステップで UI を更新できます。

        worker.DoWork += delegate(object s, DoWorkEventArgs args)
        {
            FirstHalfComputation();

            // you can report a percentage back to the UI thread, or you can send 
            // an object payload back
            int completedPercentage = 50;
            object state = new SomeObject();
            worker.ReportProgress(completedPercentage , state); 

            SecondHalfComputation();
        };

        worker.WorkerReportsProgress = true;    // this is important, defaults to false
        worker.ProgressChanged += delegate(object s, ProgressChangedEventArgs args)
        {
            int completedPercentage = args.ProgressPercentage;
            SomeObject state = args.UserState as SomeObject

            // update a progress bar or do whatever makes sense
            progressBar1.Step = completedPercentage;
            progressBar1.PerformStep();
        };
于 2013-11-03T03:24:15.297 に答える