【问题标题】:Process in background worker error后台工作者错误中的进程
【发布时间】:2012-08-09 19:06:50
【问题描述】:

在执行耗时的 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"); 


    }

【问题讨论】:

  • 你知道 C#4 更直接地支持 Python 吗?
  • 我对 Iron python 的限制是,我使用的是“Arcpy”,所以将 Arcpy 绑定到 Iron python 并不容易。

标签: c# .net process backgroundworker


【解决方案1】:

问题是BackgroundWorkerDoWork 处理程序在进程开始后立即结束,因为没有什么“等待”(因为您注释掉了proc.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

【讨论】:

  • 您的解决方案似乎有效,但我认为我在脚本级别有一个错误,因为它的行为从标准命令行行为发生了变化,所以它只有 2 个事件,第一个值为“0”和第二个空值,而我期待 10 个 int 值。
【解决方案2】:

BackGroundWorker 有一个专门为此而构建的 ReportProgress 选项。

BackgroundWorker.ReportProgress Method (Int32, Object)

【讨论】:

  • 非常感谢 Blam 先生,ReportProgress 函数是错误的根源,所以我试图找到一种解决方法来避免它。
猜你喜欢
  • 1970-01-01
  • 2011-06-13
  • 1970-01-01
  • 2015-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-29
  • 2012-07-16
相关资源
最近更新 更多