5

時間のかかる Python スクリプトの実行中に、IU をバックグラウンド ワーカーで管理して進行状況バーを表示します。

イベントが必要ないときにバックグラウンドワーカーを正常に使用しましたが、使用してOutputDataReceivedいるスクリプトは (「10」、「80」、..) などの進行状況の値を出力するため、イベントをリッスンする必要がありますOutputDataReceived

私はこのエラーを受け取ります:This operation has already had OperationCompleted called on it and further calls are illegal.この行でprogress.bw.ReportProgress(v);

2 つのバックグラウンド ワーカー インスタンスを使用しようとしました。

私が使用したコードの下:

    private void execute_script()
    {
             progress.bw.DoWork += new DoWorkEventHandler( //progress.bw is reference to the background worker instance
        delegate(object o, DoWorkEventArgs args)
        {

        System.Diagnostics.Process proc = new System.Diagnostics.Process();
        proc.StartInfo.FileName = "python.exe";
        proc.StartInfo.UseShellExecute = false;
        proc.StartInfo.Arguments = @".\scripts\script1.py " + file_path + " " + txtscale.Text;
        //proc.StartInfo.CreateNoWindow = true;
        //proc.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
        proc.StartInfo.RedirectStandardOutput = true;
        //proc.EnableRaisingEvents = true;
        proc.StartInfo.RedirectStandardError = true;
        proc.StartInfo.RedirectStandardError = true; 
        proc.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(proc_OutputDataReceived);
        proc.Start();
        proc.BeginOutputReadLine();

      //proc.WaitForExit();
        //proc.Close();
                   });

           progress.bw.RunWorkerAsync();
        }

 ///the function called in the event OutputDataReceived 
 void proc_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
    {
        //throw new NotImplementedException();
        if (e.Data != null)
        {
            int v = Convert.ToInt32(e.Data.ToString()); 
            MessageBox.Show(v.ToString());
         //   report(v);
            progress.bw.ReportProgress(v);

        }
        else
            MessageBox.Show("null received"); 


    }
4

2 に答える 2

5

問題は、プロセスが終了するのを(コメントアウトしたため)何も「待機」していないため、プロセスが開始するとすぐにBackgroundWorkerのハンドラーが終了することです。作業ハンドラーが完了すると、そのインスタンスを使用して進行状況を報告できなくなります。DoWorkproc.WaitForExit()BackgroundWorker

は既に非同期であるためProcess.Start、バックグラウンド ワーカーを使用する理由はまったくありません。OutputDataReceivedからの呼び出しを自分で UI スレッドにマーシャリングすることができます。

///the function called in the event OutputDataReceived 
void proc_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
    //throw new NotImplementedException();
    if (e.Data != null)
    {
        int v = Convert.ToInt32(e.Data.ToString()); 
        // MessageBox.Show(v.ToString());
        // progress.bw.ReportProgress(v);
        this.BeginInvoke( new Action( () => {
             this.progressBar.Value = v;
        }));
    }
}

これを使用する場合は、まったく作成しないでくださいBackgroundWorker

于 2012-08-09T19:16:01.570 に答える
0

BackGroundWorkerには、このためだけに構築されたReportProgressオプションがあります。

BackgroundWorker.ReportProgressメソッド(Int32、オブジェクト)

于 2012-08-09T19:13:10.137 に答える