簡體   English   中英

后台工作人員處理錯誤

[英]Process in background worker error

在執行耗時的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"); 


    }

問題在於, 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

BackGroundWorker具有為此目的而構建的ReportProgress選項。

BackgroundWorker.ReportProgress方法(Int32,對象)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM