C # событие барботирование - PullRequest
0 голосов
/ 09 ноября 2011

У меня небольшие проблемы с достижением следующего:

В Form1 есть две кнопки «Подтвердить» и «Отмена», также есть BackgroundWorker.Class1 имеет сложный метод обработки.

Нажатие «Validate» вызывает 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;
        }
    }

Спасибо за помощь!

Ответы [ 2 ]

2 голосов
/ 09 ноября 2011

Не зная, как работает HeavyMethod, единственный способ сделать это - заставить поток ждать завершения HeavyMethod или предоставить способ прерывания HeavyMethod из класса obj.

Можно было бы, чтобы Class1 принял ссылку на объект backgroundWorker, чтобы HeavyMethod мог проверить значение флага CancellationPending и прервать этот метод.Это будет работать только в том случае, если ваш HeavyMethod имеет цикл или набор меньших задач, в которых вы можете проверить этот флаг между задачами, чтобы прервать или вернуться к методу раньше.1005 *

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();
}
0 голосов
/ 09 ноября 2011

Ваш код 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; 

   ..... 
   ....
}

Как-то так, просто чтобы дать идею.

EDIT

Как указал Визетукс, вы должны обратить внимание на тот факт, что булево значение (в данном конкретном случае) манипулируется разными потоками.

Надеюсь, это поможет.

...