2013-07-31 64 views
2

我加入這兩條線在Form1的頂部:爲什麼背景工作者取消按鈕dosent取消背景工作操作?

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開始工作。

這是定時器Tick事件:

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

即時使用循環,但仍然不好。用我所做的更新了我的問題。 – DanielVest

+0

取消不僅僅是複製文件循環,它應該取消整個操作,如果它在DoWork事件中的其他功能的中間。所以我用while(true)循環 – DanielVest

1

您正在檢查錯誤階段的CancellationPending。

嘗試類似;

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