取消 BackgroundWorker 的正确方法
Proper way to cancel BackgroundWorker
这是我第一次使用 wpf。现有系统要处理一个excel文件,现在要求是,excel文件必须有5个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 部分,但是它继续到其他部分,然后显示一条错误消息 "done processing"。
这是执行确认消息的方法的当前代码
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;
}
}
}
我的主要问题是,这是正确的方法吗?如果不符合要求,我还有什么其他方法可以取消工作吗?
BackgroundWorker 有一个名为 WorkerSupportsCancellation
的 属性。如果将其设置为 true,您将有另一个选项来取消执行。
每当发生错误时,您可以调用backgroundWorker.CancelAsync()
,这会将布尔值设置为true(即BackgroundWorker对象中的CancellationPending
属性)。
然后您可以在执行期间检查 CancellationPending
是否为真。如果是这样,工人应该停下来。
如果 worker 停止,它将启动 RunWorkerCompleted
事件,该事件将在方法的处理程序中结束(如果添加的话)。
这种取消方式可以在所有指令中检查,或者在 for 循环的开始处检查(如:for (int i = 0; (i < x) && worker.CancellationPending; i++) ;
)
希望对您有所帮助!
使用您在 DoWork 中传递的 DoWorkEventArgs 实例的 Result 属性:
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
是对象类型。您可以将任何类型的实例放入其中,甚至是您自己的 class,如果您想要 return 关于出错原因的更详细的细节,可能需要它。
这是我第一次使用 wpf。现有系统要处理一个excel文件,现在要求是,excel文件必须有5个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 部分,但是它继续到其他部分,然后显示一条错误消息 "done processing"。
这是执行确认消息的方法的当前代码
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;
}
}
}
我的主要问题是,这是正确的方法吗?如果不符合要求,我还有什么其他方法可以取消工作吗?
BackgroundWorker 有一个名为 WorkerSupportsCancellation
的 属性。如果将其设置为 true,您将有另一个选项来取消执行。
每当发生错误时,您可以调用backgroundWorker.CancelAsync()
,这会将布尔值设置为true(即BackgroundWorker对象中的CancellationPending
属性)。
然后您可以在执行期间检查 CancellationPending
是否为真。如果是这样,工人应该停下来。
如果 worker 停止,它将启动 RunWorkerCompleted
事件,该事件将在方法的处理程序中结束(如果添加的话)。
这种取消方式可以在所有指令中检查,或者在 for 循环的开始处检查(如:for (int i = 0; (i < x) && worker.CancellationPending; i++) ;
)
希望对您有所帮助!
使用您在 DoWork 中传递的 DoWorkEventArgs 实例的 Result 属性:
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
是对象类型。您可以将任何类型的实例放入其中,甚至是您自己的 class,如果您想要 return 关于出错原因的更详细的细节,可能需要它。