2013-07-31 2 views
2

Я добавил это две строки в верхней части Form1:Почему кнопка отмены отмены фонового рисунка отменяет операцию фонового рабочего?

backgroundWorker1.WorkerReportsProgress = true; 
backgroundWorker1.WorkerSupportsCancellation = true; 

В случае нажатия кнопки запуска я добавил:

timer2.Enabled = true; 
if (this.backgroundWorker1.IsBusy == false) 
      { 
       this.backgroundWorker1.RunWorkerAsync(); 
      } 

Это событие DoWork:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
     { 
      BackgroundWorker worker = sender as BackgroundWorker; 
      if (worker.CancellationPending) 
      { 
       e.Cancel = true; 
       return; 
      } 
      if (filesContent.Length > 0) 
      { 
       for (int i = 0; i < filesContent.Length; i++) 
       { 
        File.Copy(filesContent[i], Path.Combine(contentDirectory, Path.GetFileName(filesContent[i])), true); 
       } 
      } 
      WindowsUpdate(); 
      CreateDriversList(); 
      GetHostsFile(); 
      Processes(); 
     } 

Затем завершилось мероприятие:

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 
      if ((e.Cancelled == true)) 
      { 
       this.Diagnose.Text = "THIS OPERATION HAS BEEN CANCELLED"; 
      } 
      else if (!(e.Error == null)) 
      { 
       this.Diagnose.Text = ("Error: " + e.Error.Message); 
      } 
      else 
      { 
       processfinish = true; 
      } 
     } 

В конце концов кнопки мыши отменить событие:

private void CancelOperation_Click(object sender, EventArgs e) 
     { 
      backgroundWorker1.CancelAsync(); 
     } 

Когда я нажимаю кнопку я использовал контрольную точку я видел его идти к CancelAsync отменить(); Но тогда его просто прыгает на отметку timer2 и продолжает работать. timer2 начинает работать, как только я нажал кнопку запуска.

Это событие Таймер2 клеща:

private void timer2_Tick(object sender, EventArgs e) 
     { 
      timerCount += 1; 
      TimerCount.Text = TimeSpan.FromSeconds(timerCount).ToString(); 
      TimerCount.Visible = true; 
      if (processfinish == true) 
      { 
       timer2.Enabled = false; 
       timer1.Enabled = true; 
      }       
     } 

Почему, когда я нажимаю кнопку отмены операции не останавливаться и продолжать идти регулярными? И в кнопке «Отмена» мне нужно каким-то образом удалить/очистить любые объекты или фонаря?

Это то, что я сделал в DoWork сейчас:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
     { 
      BackgroundWorker worker = sender as BackgroundWorker; 
      while (true) 
      { 
       if (worker.CancellationPending) 
       { 
        e.Cancel = true; 
        if (filesContent.Length > 0) 
        { 
         for (int i = 0; i < filesContent.Length; i++) 
         { 
          File.Copy(filesContent[i], Path.Combine(contentDirectory, Path.GetFileName(filesContent[i])), true); 
         } 
        } 
        WindowsUpdate(); 
        CreateDriversList(); 
        GetHostsFile(); 
        Processes(); 
       } 
      } 
     } 

И кнопка отмены:

private void CancelOperation_Click(object sender, EventArgs e) 
     { 
      backgroundWorker1.CancelAsync(); 
      timer2.Enabled = false; 
     } 

Но теперь в DoWork я не имею возвращение; Так что он никогда не попадает на завершенное событие, когда я нажимаю кнопку отмены и никогда не показываю сообщение this.Diagnose.Text = "ЭТОТ ОПЕРАЦИЯ ОТКАЗАНА";

Если я добавлю теперь возврат; Тогда остальная часть кода в DoWork будет недостижимым кодом

Что делать тогда?

ответ

7

Потому что ваше событие DoWork проверяет имущество CancellationPendingдо оно начинает выполнять всю тяжелую работу.

Правильный способ проверить это свойство внутри петля.

Также обратите внимание, что если вы копируете только несколько, но очень очень больших файлов и хотите отменить, даже когда он занят копированием файла, вам нужно выписать код, который можно отменить, который выполняет копирование как Что ж.

+0

Im, используя петлю, но все же ее не очень хорошо. Обновленный мой вопрос с тем, что я сделал. – DanielVest

+0

Отмена не только для цикла копирования файлов, она должна отменить всю операцию, если она находится в середине других функций в событии DoWork. поэтому я использовал цикл While (true) – DanielVest

1

Вы проверяете отмену платежей на неправильной стадии.

Попробуйте что-нибудь наподобие;

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
    { 
     BackgroundWorker worker = sender as BackgroundWorker; 
     if (filesContent.Length > 0) 
     { 
      for (int i = 0; i < filesContent.Length; i++) 
      { 
       if (worker.CancellationPending) 
       { 
        e.Cancel = true; 
        return; 
       } 
       File.Copy(filesContent[i], Path.Combine(contentDirectory, Path.GetFileName(filesContent[i])), true); 
      } 
     } 

     if (!worker.CancellationPending) 
      WindowsUpdate(); 

     if (!worker.CancellationPending) 
      CreateDriversList(); 

     if (!worker.CancellationPending) 
      GetHostsFile(); 

     if (!worker.CancellationPending) 
      Processes(); 

     if (worker.CancellationPending) 
      e.Cancel = true; 
    } 
Смежные вопросы