我有一个可以取消的后台工作人员。
当CancelPending变量变为true时,正常流程会自行中断(响应UI上的用户交互,调用worker.CancelAsynch()),抛出异常,因为如果那样(因为正常流程被中断,很多空引用异常都是抛出)
因此,当工作者返回时,我希望能够区分工作时抛出的异常 被取消(默默地忽略它们)从未取消工作时抛出的异常(向UI报告)。
我的代码如下(抱歉c#/ vb mix ...):
工人阶级:
Public Class ClassBaseGetObjectsWorker
Inherits System.ComponentModel.BackgroundWorker
Protected Overrides Sub OnDoWork(ByVal e As System.ComponentModel.DoWorkEventArgs)
Try
Dim cpt As Int16 = 0
While cpt < 5
System.Threading.Thread.Sleep(1000)
cpt = cpt + 1
If CheckForCancellation() Then
'Simulating exception due to cancel
Throw New Exception("Exception du to cancel !")
End If
End While
Catch exc As Exception
e.Cancel = Me.CancellationPending
Throw exc
End Try
End Sub
End Class
回电:
void setObjSetCollWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
if (e.Cancelled) {
resultLabel.Text += "Canceled";
//e.Error is selently ignored
}
else {
if (e.Error != null) {
//Reporting errors arising during normal (uncanceled) flow
throw e.Error.InnerException;
}
else {
//Worker process finished without error or being canceled.
updateUIAfterBackgroundJob();
}
}
}
然后,当我正在做worker.CancelAsynch()时,e.Cancelled在Completed回调中设置为false(这不是我的预期)。如果我在工作人员中评论“Trow exc”,如果我测试的话 再次,e.Cancelled正确设置为true。
那么,获取我想要的信息的最简洁方法是什么,即:我想知道当工作者处于cancelPending状态时是否抛出了在已完成的处理程序中弹出的异常。
(抱歉我的英语不好)
答案 0 :(得分:0)
如果在OnDoWork()实现中构造代码的最佳方法是在检测到取消时抛出异常,请执行以下操作:
创建一个CancelException:
public class CancelException: Exception {}
当您检测到取消待处理时抛出此CancelException:
if(CheckForCancellation()) throw new CancelException();
在OnDoWork()方法代码中添加try-catch:
protected override void OnDoWork(DoWorkEventArgs e){
try{
//...
}
catch(CancelException){
// silently return
return;
}
}
这样你的代码就会遵守BackgroundWorker-contract(当你检测到取消挂起时从OnDoWork()返回,而不是抛出异常),而且Canceled属性现在应该如你所愿