2012-08-09 8 views
5

während der Ausführung eines zeitaufwendigen Python-Skript, würde ich die IU mit Hintergrund-Worker verwalten, um eine Fortschrittsanzeige anzuzeigen.Prozess im Hintergrund worker Fehler

Ich habe den Hintergrund-Arbeiter erfolgreich verwendet, wenn ich nicht das Ereignis OutputDataReceived brauche, aber das Skript, das ich verwende, druckt einige Fortschrittswerte wie ("10", "80", ..), also habe ich Hören Sie das Ereignis OutputDataReceived.

Ich erhalte diesen Fehler: This operation has already had OperationCompleted called on it and further calls are illegal. in dieser Zeile progress.bw.ReportProgress(v);.

i2 Hintergrund Arbeiter Instanzen zu verwenden versucht, kann man versuchen und die anderen zuhört, gibt es keine Fehler, aber es scheint nicht vom Ausgang nennen OutputDataReceived 'Ich sehe so keinen Fortschritt in der Statusleiste.

unter dem Code, den ich verwendet:

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

Sie wissen, dass C# 4 Python etwas direkter unterstützt? –

+0

meine contraint zu Iron python ist das, ich benutze "Arcpy" so verbindlich Arcpy zu Iron Python ist nicht ganz einfach. – geogeek

Antwort

5

Das Problem ist, dass die BackgroundWorker ‚s DoWork Handler beendet, sobald der Prozess beginnt, da gibt es nichts‚warten‘für den Prozess zu beenden (da Sie proc.WaitForExit() kommentiert out). Sobald der Arbeitshandler BackgroundWorker fertig ist, können Sie den Fortschritt nicht mehr mit dieser Instanz melden.

Da Process.Start bereits asynchron ist, gibt es keinen Grund, einen Hintergrundarbeiter überhaupt zu verwenden. Sie können nur der Anruf Marschall von OutputDataReceived auf dem UI-Thread selbst:

///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; 
     })); 
    } 
} 

Wenn Sie diese verwenden, erstellen Sie keine der BackgroundWorker überhaupt.

+0

Ihre Lösung scheint zu funktionieren, aber ich denke, dass ich einen Fehler in der Skript-Ebene habe, weil sein Verhalten von Standard-Befehlszeilenverhalten ändert, so hat es nur zwei Ereignisse eins mit dem ersten Wert "0" und das zweite mit Null-Wert, während ich erwarte 10 Werte von int. – geogeek

Verwandte Themen