处理后台工作程序错误

时间:2012-08-09 19:06:50

标签: c# .net process backgroundworker

执行耗时的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个后台工作器实例,一个执行而另一个侦听,它没有给出任何错误,但它似乎没有调用事件'OutputDataReceived'所以我没有在进度条中看到任何进展。

在我使用的代码下面:

    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"); 


    }

2 个答案:

答案 0 :(得分:5)

问题是BackgroundWorker的{​​{1}}处理程序在进程启动后立即结束,因为没有任何“等待”(因为您已注释掉DoWork)进程到完。 proc.WaitForExit()工作处理程序完成后,您将无法再使用该实例报告进度。

由于BackgroundWorker已经异步,因此根本没有理由使用后台工作程序。您可以自己将来自Process.Start的呼叫编组到UI线程上:

OutputDataReceived

如果您使用此功能,请不要创建///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; })); } }

答案 1 :(得分:0)

BackGroundWorker有一个仅为此构建的ReportProgress选项。

BackgroundWorker.ReportProgress Method (Int32, Object)