我有一个C#
应用程序,它执行一个返回Task的方法。在这种情况下,如果被调用的方法抛出异常,我正在尝试显示一个包含异常详细信息的消息框。
如果我这样称呼它,我可以在task.Exception
中看到异常:
MyClass.MyAsyncMethod(cancellationToken)
.LogExceptions()
.ContinueWith(task => {
MessageBox.Show(task.Exception);
}, cancellationToken, TaskContinuationOptions.NotOnRanToCompletion, TaskScheduler.Default);
但是,如果我添加OnlyOnRanToCompletion
延续,task.Exception
续语中的NotOnRanToCompletion
将变为空:
MyClass.MyAsyncMethod(cancellationToken)
.LogExceptions()
.ContinueWith(task => {
Log.Info("Executed");
}, cancellationToken, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default)
.ContinueWith(task => {
MessageBox.Show(task.Exception);
}, cancellationToken, TaskContinuationOptions.NotOnRanToCompletion, TaskScheduler.Default);
OnlyOnranToCompletion
延续中的代码未执行,但NotOnRanToCompletion
延续中的代码已执行且task.Exception
为空。为什么会这样?
注意:我无法使用C# >= 5.0
或async
等await
功能。我也可以通过一个None
延续方法来解决这个问题,该方法检查任务的异常参数并确定是否发生了异常。但是,我对为什么会发生上述行为感兴趣。
这是被调用的方法:
public Task<bool> MyAsyncMethod(CancellationToken cancellationToken)
{
return Task<bool>.Factory.StartNew(() =>
{
...
try
{
var response = request.GetResponse();
if (response.StatusCode != HttpStatusCode.OK)
throw new Exception("Invalid response status code: " + response.StatusCode);
}
catch (Exception ex)
{
Logger.Error("Request failed", ex));
throw;
}
}, cancellationToken, TaskCreationOptions.None, TaskScheduler.Default);
}
答案 0 :(得分:4)
没有例外,因为它是继续的Task
没有抛出异常。 Task
它的延续(前一次调用ContinueWith
)将成功完成。
如果你想同时处理错误和非错误情况,你可能最好只有一个延续并检查它是否在该延续中成功,而不是使用延续选项。或者,您可以将Task
存储在您正在进行的实际工作中,并将两个延续作为Task
的延续,而不是将一个延续作为另一个的延续。