链式C#任务继续中的任务异常为空
我有一个链式C#任务继续中的任务异常为空,c#,asynchronous,task,C#,Asynchronous,Task,我有一个C应用程序,它执行一个返回。在本例中,如果调用的方法引发异常,我将尝试显示一个包含异常详细信息的消息框 如果我这样称呼它,我可以在task.exception中看到异常: MyClass.MyAsyncMethod(cancellationToken) .LogExceptions() .ContinueWith(task => { MessageBox.Show(task.Exception); }, cancell
C
应用程序,它执行一个返回。在本例中,如果调用的方法引发异常,我将尝试显示一个包含异常详细信息的消息框
如果我这样称呼它,我可以在task.exception
中看到异常:
MyClass.MyAsyncMethod(cancellationToken)
.LogExceptions()
.ContinueWith(task => {
MessageBox.Show(task.Exception);
}, cancellationToken, TaskContinuationOptions.NotOnRanToCompletion, TaskScheduler.Default);
但是,如果我添加了一个OnlyOnRanToCompletion
延续,则非自动完成
延续中的task.Exception
将变为null:
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
延续中的代码,并且任务。异常
为空。为什么会发生这种情况?
注意:我不能使用C#>=5.0
功能,如async
或wait
。我还可以通过在一个None
continuation方法下检查任务的异常参数并确定是否发生异常来解决这个问题。然而,我感兴趣的是为什么会发生上述行为
这是被调用的方法:
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);
}
公共任务MyAsyncMethod(CancellationToken CancellationToken)
{
返回Task.Factory.StartNew(()=>
{
...
尝试
{
var response=request.GetResponse();
if(response.StatusCode!=HttpStatusCode.OK)
抛出新异常(“无效响应状态代码:“+response.StatusCode”);
}
捕获(例外情况除外)
{
Logger.Error(“请求失败”,ex));
投掷;
}
},cancellationToken,TaskCreationOptions.None,TaskScheduler.Default);
}
没有异常,因为作为其延续的
任务未引发异常。作为其延续的任务
(上一次调用ContinueWith
)将成功完成
如果您想同时处理错误和非错误情况,最好只使用一个延续并检查该延续是否成功,而不是使用延续选项。或者,您可以存储您正在执行的实际工作中的任务
,并将两个延续作为延续添加到该任务
,而不是让一个延续成为另一个延续。没有异常,因为作为延续的任务没有抛出异常。作为其延续的任务
(上一次调用ContinueWith
)将成功完成
如果您想同时处理错误和非错误情况,最好只使用一个延续并检查该延续是否成功,而不是使用延续选项。或者,您可以存储您正在执行的实际工作中的任务
,并将两个延续作为延续添加到该任务
,而不是将一个延续作为另一个延续。现在这就非常有意义了。非常感谢。这很有道理。非常感谢。请注意,错误处理如此困难和乏味是添加await
的一个重要原因,因为它大大简化了正确的错误处理。同意,虽然在我的情况下无法升级到新版本。请注意,错误处理如此困难和繁琐是添加await
的一个重要原因,因为它大大简化了正确的错误处理。同意,但在我的情况下无法升级到新版本。