C#事件冒泡

时间:2011-11-08 20:32:37

标签: c# winforms events backgroundworker

我在实现以下方面遇到了一些麻烦:

Form1有两个按钮“Validate”和“Cancel”,还有一个BackgroundWorker。 Class1有一个繁重的处理方法。

单击“验证”会调用DoWork,其中繁重的工作是Class1的方法。我已经设法“监听”我的DoWork中的进度更改事件,这些事件来自Class1方法。

现在,当点击按钮取消时,我正试图取消沉重的dutty(在方法内)。

private void buttonCancelValidation_Click(object sender, EventArgs e)
    {
        backgroundWorker.CancelAsync();
    }

    private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        Class1 obj = new Class1();
        obj.ProgressChanged += (s, pe) => backgroundWorker.ReportProgress(pe.ProgressPercentage);

        //---> Here a i'm trying to "tell" class1 that if the "Cancel" button was clicked then I want to abort ASAP the HeavyMethod operation.

        obj.HeavyMethod();

        //followed by the cancel of BackgroundWorker DoWork
        if (backgroundWorker.CancellationPending  
        {
            e.Cancel = true;
        }
    }

感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

在不知道HeavyMethod如何工作的情况下,你可以做到这一点的唯一方法是让线程等到HeavyMethod完成,或者提供一种方法来从obj类中中断HeavyMethod。

您可以让Class1接受对backgroundWorker对象的引用,以便HeavyMethod可以检查CancellationPending标志的值并在该方法中中断。这只适用于您的HeavyMethod有一个循环或一组较小的任务,您可以在这些任务中检查任务之间的这个标志,以便提前中断或从方法返回。

你可以像这样完成这个

public class Class1
{
   private BackgroundWorker _backgroundWorker = null;
   public Class1(BackgroundWorkerThread worker)
   {
     _backgroundWorker = worker;
     // rest of constructor
   }

   public void HeavyWorker()
   {
      // Heavy work

      // Have we been cancelled.
      if (_backgroundWorker != null && _backgroundWorker.CancellationPending)
      {
         // perform clean up and return
      }

       // Perform more heavy work.
   }
} 

private void backgroundWorker_DoWork(...)
{
   Class1 obj = new Class1(backgroundWorker);

   obj.HeavyMethod();
}

答案 1 :(得分:0)

你的HeavyMethod()代码必须能够访问一些,比方说布尔变量,它应该指示是否需要立即返回。在HeavyMethod()代码中检查变量值的频率会改变用户单击“取消”按钮和实际停止的操作之间的延迟。

bool cancelValidationRequest = false; 
private void buttonCancelValidation_Click(object sender, EventArgs e)
    {
        cancelValidationRequest = true; // this will cause HeavyMethod return asap
        backgroundWorker.CancelAsync(); // this makes requet to thread to stop, but it still in HeavyMethod...
    }

HeavyMethod()

private void HeavyMethod() 
{   

    //execute heavy code 
    if(cancelValidationRequest ) return; 

   // continue execute heavy code 
    if(cancelValidationRequest ) return; 

   ..... 
   ....
}

这样的东西,只是为了给出一个想法。

修改

正如Wizetux指出的那样,你必须注意bolean值(在这种特定情况下)由不同的线程操纵的事实。

希望这有帮助。