2012-08-09 16 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つのバックグラウンドワーカーインスタンスを使用しようとしましたが、1つは実行され、もう1つはリッスンしますが、エラーは発生しませんが、イベント '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を少し直接サポートしていることは知っていますか? –

+0

Iron Pythonへの私の関わりは、ArcpyをIron pythonにバインドするのはかなり簡単ではないので、 "Arcpy"を使用しています。 – geogeek

答えて

5

問題は(あなたがproc.WaitForExit()をコメントアウトするので)、プロセスが終了するのを何も 『待機』がないようBackgroundWorkerDoWorkハンドラは、とすぐに処理を開始すると終了していることです。 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; 
     })); 
    } 
} 

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

+0

あなたの解決策は動作しているようですが、スクリプトの動作が標準的なコマンドラインの動作から変わるので、スクリプトレベルでエラーが発生していると思いますので、最初の値が「0」の2イベント、 intの10の値を期待しています。 – geogeek

0

BackgroundWorkerのは、このためだけに構築されてReportProgressオプションがあります:私が使用したコード以下

BackgroundWorker.ReportProgress Method (Int32, Object)

+0

質問やコメントはありません。ちょうど下の投票。どうして? – Paparazzi

+0

ありがとうMr Blam、ReportProgress関数がエラーの原因であったため、回避するための回避策を見つけようとしました。 – geogeek