2012-08-09 67 views
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個後臺工作者實例,一個執行,另一個監聽,它沒有提供任何錯誤,但它似乎不會調用事件'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"); 


    } 
+1

你知道C#4更直接地支持Python嗎? – 2012-08-09 19:21:27

+0

我對Iron python的限制是,我使用「Arcpy」,因此將Arcpy綁定到Iron python不是很容易。 – geogeek 2012-08-09 20:30:03

回答

5

的問題是,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可言。

+0

你的解決方案似乎工作,但我認爲我有腳本級別的錯誤,因爲它的行爲從標準命令行行爲改變,所以它只有2個事件之一與第一個值「0」和第二個空值,而我期待int的10個值。 – geogeek 2012-08-09 20:50:55