【问题标题】:Wait for BackgroundWorker RunWorkerCompleted等待 BackgroundWorker RunWorkerCompleted
【发布时间】:2011-05-07 13:43:40
【问题描述】:

在主线程中我有一个Timer。在Tick 事件中,我运行BackgroundWorker。我在那里做了一些事情,然后BackgroundWorker 调用RunWorkerCompleted 事件。

在主线程中我有函数Stop。此函数禁用Timer。但是我想等他工作的时候BackgroundWorker

例如:

public void Next()
{

    // Start the asynchronous operation
    if (!this._backgroundWorker.IsBusy)
        this._backgroundWorker.RunWorkerAsync();

}

private void _backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    DoSomething();

}


private void _backgroundWorker_RunWorkerCompleted(object sender, 
    RunWorkerCompletedEventArgs e)
{
    DoSomethingElse();
}

public void Stop()
{
    this._timer.Enabled = false;
}

所以我的问题是如何等待BackgroundWorkerRunWorkerCompleted 事件?我需要等到DoSomethingElse(); 完成。

谢谢

【问题讨论】:

  • 没有。您无需等待后台工作人员..这就是为什么它被称为后台工作人员-您的应用程序在后台工作人员工作时继续做事。您将一个事件侦听器附加到您的应用程序,该事件侦听器应在后台工作人员完成后触发,然后处理数据。
  • Private Sub backgroundWorker1_RunWorkerCompleted(_ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) _ Handles backgroundWorker1.RunWorkerCompleted

标签: c# .net multithreading backgroundworker


【解决方案1】:

处理后台操作完成、取消或引发异常时发生的BackgroundWorker.RunWorkerCompleted事件。

// This event handler deals with the results of the
// background operation.

private void backgroundWorker1_RunWorkerCompleted(
    object sender, RunWorkerCompletedEventArgs e)
{
    // First, handle the case where an exception was thrown.
    if (e.Error != null)
    {
    }
    else if (e.Cancelled)
    {
        // Next, handle the case where the user canceled 
        // the operation.
        // Note that due to a race condition in 
        // the DoWork event handler, the Cancelled
        // flag may not have been set, even though
        // CancelAsync was called.
    }
    else
    {
        // Finally, handle the case where the operation 
        // succeeded.
    }

}

【讨论】:

    【解决方案2】:

    如果您只需要两个线程,请允许调用 this._backgroundWorker.RunWorkerAsync(); 的线程 在它调用此方法并在 DoSomethingElse() 之后调用任何你想发生的事情后死亡;在同一个区块内

            private void _backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
    
    DoSomethingElse();
    DoSomethingAfterSomethingElse();
    
            }
    

    否则,您将暂停一个线程以启动另一个线程然后返回,这违背了多线程的目的?

    【讨论】:

      【解决方案3】:

      我认为 BackgroundWorker.IsBusy 属性是在这种情况下可以帮助您的唯一成员。希望下面的逻辑能满足你的需要。

      //Add a class member
      private bool stopped;
      
      public void Stop() 
      {    
           if (!this._backgroundWorker.IsBusy)
           {
               this._timer.Enabled = false; 
               stopped = false;
           }
           else
           {
               stopped = true;
           }
      
      } 
      
      private void _backgroundWorker_RunWorkerCompleted(object sender,      RunWorkerCompletedEventArgs e) 
      {     
           DoSomethingElse(); 
      
          if (stopped)
          {
                   this._timer.Enabled = false; 
                   stopped = false;
          }
      } 
      

      【讨论】:

        【解决方案4】:

        这是一种在后台工作人员完成之前停止/冻结主线程的方法:

        public void Stop()
        {
            if (!_backgroundWorker.IsBusy)
            {
                _timer.Enabled = false;
        
                // Stop/Freeze the main thread until the background worker finishes 
                while (_backgroundWorker.IsBusy)
                {
                    Thread.Sleep(100);
                }
            }
        }
        

        现在,如果您的应用程序使用表单,我将禁用整个表单并显示消息,让用户知道应用程序正在等待进程完成。您还可以使用标志来禁用表单关闭。

        private bool _canClose;
        
        public void Stop()
        {
            if (!_backgroundWorker.IsBusy)
            {
                _timer.Enabled = false;
                // Don't let the user do anything in the form until the background worker finishes
                this.IsEnabled = false;
                _label.Text = "Waiting for the process to finish";
                _canClose = false; 
            }
         }
        private void _backgroundWorker_RunWorkerCompleted(object sender,
            RunWorkerCompletedEventArgs e)
        {
            DoSomethingElse();
            // Allow the user to close the form
            this.IsEnabled = true;
            _canClose = true;
        }
        
        private void MainWindow_Closing(object sender, CancelEventArgs e)
        {
            e.Cancel = !_canClose;
        }
        

        【讨论】:

          猜你喜欢
          • 2011-02-17
          • 1970-01-01
          • 1970-01-01
          • 2011-11-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多