2017-08-03 65 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++) ;)的这种方式

希望这有助于!