C# 事件冒泡

发布于 2024-12-14 06:30:28 字数 945 浏览 1 评论 0原文

我在实现以下目标时遇到了一些麻烦:

Form1 有两个按钮“验证”和“取消”,还有一个BackgroundWorker。 Class1有较重的处理方法。

单击“Validate”会调用DoWork,该DoWork 是Class1 的方法。我已经成功地“监听”DoWork 中由 Class1 方法产生的进度更改事件。

现在,我试图在单击“取消”按钮时取消繁重的任务(在方法内)。

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

感谢您的帮助!

I'm having a little trouble to achieve the following:

Form1 has two buttons "Validate" and "Cancel", also has a BackgroundWorker.
Class1 has a heavy processing method.

Clicking "Validate" calls the DoWork which heavy work is a method of Class1. I've managed to "listen" for progress changes events in my DoWork, that arise from Class1 method.

Now, I'm trying to cancel the heavy dutty (inside the method) when the button Cancel is clicked.

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

Thanks for the help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

盛夏尉蓝 2024-12-21 06:30:28

在不知道 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();
}

Without knowing how the HeavyMethod works, the only way you can do this is to have the thread wait until the HeavyMethod completes, or provide a way to interupt the HeavyMethod from within the obj class.

You could have Class1 accept a reference to the backgroundWorker object so that the HeavyMethod could check the value of the CancellationPending flag and break in that method. This would only work if your HeavyMethod has a loop or a set of smaller tasks in which you can check this flag between the tasks in order to break or return from the method early.

You could accomplish this like so

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();
}
鸢与 2024-12-21 06:30:28

您的 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指出的,您必须注意布尔值(在这种特定情况下)是由不同线程操纵的事实。

希望这有帮助。

Your HeavyMethod() code has to be able to access some, let's say boolean, variable which should indicate if it need to return immediately. How often you will check for that variable value inside HeavyMethod() code will vary the latency between the moment user clicked Cancel button and action actually stopped.

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...
    }

and inside HeavyMethod()

private void HeavyMethod() 
{   

    //execute heavy code 
    if(cancelValidationRequest ) return; 

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

   ..... 
   ....
}

Something like this, just to give an idea.

EDIT

As Wizetux pointed out, you have to pay attention on the fact that bolean value (in this specific case) is manipulated by different threads.

Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文