2017-08-03 63 views
0

它是我第一次工作在WPF。現有的系統必須處理一個excel文件,現在需求是,excel文件必須有五個comlumns。這是必須做的處理正確的方法取消BackgroundWorker

void InsertIDsNamesAndAddWorker_DoWork(object sender, DoWorkEventArgs e) 
      { 
       // read the excel file here 
       int columns = xlWorkSheet.UsedRange.Columns.Count; 
       if (columns == 5) 
       { 
        //do your normal processing 
       } 
       else 
       { 
        //if requirements are not met then display error message 
        System.Windows.MessageBox.Show("There must be five columns in this 
        file", MessageBoxButton.OK, MessageBoxImage.Error); 
       } 
      } 

下面這段代碼並進入其他部分的代碼,但是它繼續其他部分,然後顯示,上面寫着「做了處理」的錯誤消息。

下面是確實的確認消息

void InsertIDsNamesAndAddWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
      { 
       ProgressBarValue = 100; 
       StatusLable = "Done Processing."; 
       if (System.Windows.MessageBox.Show("Done Processing.", "Status", MessageBoxButton.OK, MessageBoxImage.Information) == MessageBoxResult.OK) 
       { 
        StatusLable = string.Empty; 
        ProgressBarValue = 0; 
       } 
      } 

現在與我是新來的WPF技術方法的當前代碼,我意識到Statuslable的硬編碼值是一個引起問題,所以我去設置ProgressBarValue爲100如果滿足要求和處理完成。 我還設置了ProgressBarValue爲零,如果colums不等於5 這是新代碼

void InsertIDsNamesAndAddWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
      { 
       int count = ProgressBarValue; 
       if (count != 100) 
       { 
        StatusLable = string.Empty; 
        ProgressBarValue = 0; 
       } 
       else 
       { 
        //ProgressBarValue = 100; 
        StatusLable = "Done Processing."; 
        if (System.Windows.MessageBox.Show("Done Processing.", "Status", MessageBoxButton.OK, MessageBoxImage.Information) == MessageBoxResult.OK) 
        { 
         StatusLable = string.Empty; 
         ProgressBarValue = 0; 
        } 
       } 

      } 

我的主要問題是,這是正確的做法,但?如果不符合要求,我可以通過其他方式取消工作嗎?

+0

如果您正在驗證工作進程中的列數(您可能想要執行的操作,出於性能/用戶界面可用性原因),我認爲您不會「取消」該工作;相反,你提前停止工作並注意結果。這可能是哲學的,但我認爲其他線程/進程是「取消」線程的線程/進程。雷內的答案似乎是一個好方法。 –

+0

這是關於處理錯誤並在完成的事件中取消的[舊回答](https://stackoverflow.com/a/4807200/60761)。 –

+0

@VinceI - 取消自己可能是一種可接受的方式,表明答案是無效的。 –

回答

2

使用Result prorperty你在DoWork的通過DoWorkEventArgs實例:

void InsertIDsNamesAndAddWorker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    if (columns == 5) 
    { 
     //do your normal processing 
     e.Result = true; // we're OK 
    } 
    else 
    { 
     //if requirements are not met then display error message 
     System.Windows.MessageBox.Show("There must be five columns in this 
     file", MessageBoxButton.OK, MessageBoxImage.Error); 

     e.Result = false; // something wrong 
    } 
} 

,然後在RunWorkerCompleted檢查Result值和相應的處理。

void InsertIDsNamesAndAddWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    // check if we're not cancelled or error-ed before checking the Result 
    result = (!e.Cancelled && e.Error == null)? (bool) e.Result: false; // what is the outcome 

    ProgressBarValue = 100; 
    if (result) { 
     StatusLable = "Done Processing."; 
     if (System.Windows.MessageBox.Show("Done Processing.", "Status", MessageBoxButton.OK, MessageBoxImage.Information) == MessageBoxResult.OK) 
     { 
      StatusLable = string.Empty; 
      ProgressBarValue = 0; 
     } 
    } 
    else 
    { 
     StatusLable = "Error in Excel sheet"; 
    } 
} 

請注意,Result是對象類型。你可以把任何類型的實例放入它,甚至是你自己的類中,如果你想返回關於錯誤的細節細節,可能需要這個類。

2

BackgroundWorker具有名爲WorkerSupportsCancellation的屬性。如果這設置爲true,那麼您有另一個選項可以取消執行。

每當發生錯誤時,可以調用backgroundWorker.CancelAsync(),它會將布爾值設置爲true(這是BackgroundWorker對象中的CancellationPending屬性)。

然後,您可以在執行期間檢查CancellationPending是否爲真。如果是這樣,那麼工人應該停下來。

如果工作人員停止,它將啓動RunWorkerCompleted事件,該事件最終將在該方法的處理程序中(如果有添加的話)。

取消,可以檢查在所有的指令,或者在for循環的開始(如:for (int i = 0; (i < x) && worker.CancellationPending; i++) ;)的這種方式

希望這有助於!