后台工作者:取消期间出现异常
我有一个可以取消的后台工作者。
当 CancelPending 变量变为 true 时,正常流程会自行中断(响应 UI 上调用 worker.CancelAsynch() 的用户交互),则会引发异常,因为如果出现这种情况(由于正常流程被中断,则会引发大量 null ref 异常),
因此当工作人员返回时,我希望能够区分工作人员返回时抛出的异常 被取消(以默默地忽略它们),因为当工作人员未取消时抛出异常(以将其报告给 UI)。
我的代码如下(对于 c#/vb 混合感到抱歉...):
工人类:
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 设置为 false (这不是我所期望的)在已完成的回调中。 如果我在工作人员中注释掉“Trow exc”,如果我再次测试,e.Cancelled 会正确设置为 true。
获取我想要的信息的最干净的方法是什么,即:我想知道当工作线程处于cancelPending状态时,完成的处理程序中弹出的异常是否抛出?
I have a background worker which can be cancelled.
The normal flows interrupt itself when the CancelPending variable turns to true (responding to user interaction on UI which call worker.CancelAsynch() ), exceptions are thrown because if that (since normal flow is interrupted, lots of null ref exception are thrown)
So when the worker returns, I want to be able to distinguish exception that have been thrown when the worker
was canceled (to silently ignore them) from exceptions thrown when worker was not canceled (to report them to UI).
My code is as follow (sorry for the c#/vb mix ...) :
The worker class:
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
The call back:
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();
}
}
}
Then, when I'm doing worker.CancelAsynch(), e.Cancelled is set to false (which is not what I expected) in the Completed call back. If I comment out "Trow exc" in the worker, if I test again, e.Cancelled is correctly set to true.
What is the cleanest way to get the information I want, that is: I want to know if the exception popping out in the completed handler was thrown when the worker was in the cancellationPending state or not?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果在 OnDoWork() 实现中构建代码的最佳方法是在检测到取消时抛出异常,请执行以下操作:
创建 CancelException:
在检测到取消挂起时抛出此 CancelException:
在周围添加一个 try-catch OnDoWork() 方法中的代码:
这样您的代码将遵守 BackgroundWorker 契约(当您检测到取消挂起时从 OnDoWork() 返回,而不是抛出异常),并且 Canceled 属性现在应该是如你所料
If the best way to structure the code in your OnDoWork()-implementation is to throw an exception when you detect cancellation, do the following:
Create a CancelException:
Throw this CancelException when you detect that cancellation is pending:
Add a try-catch around the code in your OnDoWork()-method:
That way your code will obey the BackgroundWorker-contract (which is to return from OnDoWork() when you detect cancellation pending, rather than to throw an exception), and the Cancelled property should now be as you expect