Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
链式C#任务继续中的任务异常为空_C#_Asynchronous_Task - Fatal编程技术网

链式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
的一个重要原因,因为它大大简化了正确的错误处理。同意,但在我的情况下无法升级到新版本。