正确的方法取消BackgroundWorker

时间:2017-08-03 13:48:10

标签: c# wpf backgroundworker

这是我第一次使用wpf。现有系统必须处理excel文件,现在要求是,excel文件必须有五个comlumns。这是必须进行处理的代码

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

现在这段代码确实进入了else部分,然而它继续到其他部分,然后显示一条错误消息“完成处理”。

以下是执行确认消息的方法的当前代码

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。 如果列不等于5,我还将ProgressBarValue设置为零。 这是新代码

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

            }

我的主要问题是,这是正确的方法吗?如果不满足要求,我可以取消工作吗?

2 个答案:

答案 0 :(得分:2)

BackgroundWorker有一个名为WorkerSupportsCancellation的属性。如果设置为true,则您还有另一个选项可以取消执行。

每当出现错误时,您可以调用backgroundWorker.CancelAsync(),这会将布尔值设置为true(这是BackgroundWorker对象中的CancellationPending属性。)

然后,您可以在执行期间检查CancellationPending是否为真。如果是这样,工人应该停止。

如果工作人员停止,它将启动RunWorkerCompleted事件,该事件将最终出现在该方法的处理程序中(如果有任何添加)。

可以在所有说明中或在for循环开始时检查这种取消方式(如:for (int i = 0; (i < x) && worker.CancellationPending; i++) ;

希望这有帮助!

答案 1 :(得分:2)

使用您在DoWork中传递的DoWorkEventArgs实例的Result prorperty:

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是object类型。您可以将任何类型的实例放入其中,甚至是您自己的类,如果您想要返回有关错误的详细信息,可能需要这些实例。