C# 处理带有任务的异步方法的异常时出现问题

C# 处理带有任务的异步方法的异常时出现问题,c#,asynchronous,C#,Asynchronous,我希望你能帮我解决那个问题 我有一个执行特定操作的方法,例如,我正在发送一个HttpWebRequest。在那里我可以得到一个WebException,所以我把它放在一个Try-Catch块中,以便为更具体的异常消息重新显示异常 这样:(这是一个名为doWebRequest的方法) 当我正常调用这个函数时,这是可行的。 但现在我想要一种异步方式来实现这一点。在异步方法中调用此方法的步骤: public void DoRequestAsync() { Task internalReques

我希望你能帮我解决那个问题

我有一个执行特定操作的方法,例如,我正在发送一个HttpWebRequest。在那里我可以得到一个WebException,所以我把它放在一个Try-Catch块中,以便为更具体的异常消息重新显示异常

这样:(这是一个名为doWebRequest的方法)

当我正常调用这个函数时,这是可行的。 但现在我想要一种异步方式来实现这一点。在异步方法中调用此方法的步骤:

public void DoRequestAsync() 
{
   Task internalRequest = new Task(doWebRequest);
   internalRequest.ContinueWith(InternalUpdateSearchExceptionHandler, TaskContinuationOptions.OnlyOnFaulted);
   internalRequest.Start();
}
因此,这会生成一个新任务,然后调用方法doWebRequestasync。 为了现在处理错误,因为我知道它在异步上是不同的,所以我制作了这个处理程序,您也可以在internalRequest.ContinueWith中看到。看起来是这样的:

private void InternalUpdateSearchExceptionHandler(Task task)
{
  var ex = task.Exception;
  if (ex.InnerException is WebException)
  {
     if ((ex.InnerException as WebException).Status == WebExceptionStatus.ProtocolError)
     {
        throw new WebException(ex.InnerException.Message);
     }

     else
     {
        throw new Exception("There was no response from the server.");
     }
  }
}
但这并不是执行任何异常。我不知道为什么。 起初我认为,这是因为它不能将InnerException作为WebException,或者这样行吗?如果没有,请告诉我怎么办。但即使我在这里抛出一个没有任何查询的异常,它在调试时也不会抛出任何异常。为什么呢


谢谢你的帮助。当有什么不清楚的时候,问我

您的继续操作正在引发异常,但当该继续操作引发异常时,所发生的只是表示该继续操作的
任务
被标记为有故障,而给定的异常作为其异常。您当前正在忽略通过调用
ContinueWith
创建的任务,因此不存在此异常

DoRequestAsync
很可能不应该是
void
;相反,它应该返回一个
任务,特别是通过调用
ContinueWith
创建的任务,以便调用此方法的人可以观察抛出的任何异常

还请注意,您可以更简单地使用
async

public async Task DoRequestAsync() 
{
    try 
    {
        var content = await new WebClient()
            .DownloadStringTaskAsync("address");
    }
    catch (WebException ex)
    {
      throw new WebException(String.Format("My special additional message {0}", ex.Message);
    }
}

您的继续操作正在引发异常,但当该继续操作引发异常时,所发生的只是表示该继续操作的
任务
,该继续操作被标记为有故障,而给定的异常作为其异常。您当前正在忽略通过调用
ContinueWith
创建的任务,因此不存在此异常

DoRequestAsync
很可能不应该是
void
;相反,它应该返回一个
任务,特别是通过调用
ContinueWith
创建的任务,以便调用此方法的人可以观察抛出的任何异常

还请注意,您可以更简单地使用
async

public async Task DoRequestAsync() 
{
    try 
    {
        var content = await new WebClient()
            .DownloadStringTaskAsync("address");
    }
    catch (WebException ex)
    {
      throw new WebException(String.Format("My special additional message {0}", ex.Message);
    }
}

我使用的是.NET4.0,因此AsyncAwait不是适合我的解决方案;)所以,谢谢你的解释。如果我让doRequestAsync成为一个任务,那么在我的例子中“return”是什么样子的?@Trade如我所说,您只需返回由
ContinueWith创建的任务即可。因此,我现在有了:return internalRequest.ContinueWith(InternalUpdateSearchExceptionHandler,TaskContinuationOptions.OnlyOnFaulted);但就这些吗?我现在有点困惑。我对此进行了测试,但没有出现异常。@我想调用该方法的任何东西都只是忽略它返回的
任务
,而不是检查它并在它出现故障时执行某些操作。好的,我明天将再次查看它,然后看看我将做什么。谢谢我使用的是.NET4.0,因此AsyncAwait不是适合我的解决方案;)所以,谢谢你的解释。如果我让doRequestAsync成为一个任务,那么在我的例子中“return”是什么样子的?@Trade如我所说,您只需返回由
ContinueWith创建的任务即可。因此,我现在有了:return internalRequest.ContinueWith(InternalUpdateSearchExceptionHandler,TaskContinuationOptions.OnlyOnFaulted);但就这些吗?我现在有点困惑。我对此进行了测试,但没有出现异常。@我想调用该方法的任何东西都只是忽略它返回的
任务
,而不是检查它并在它出现故障时执行某些操作。好的,我明天将再次查看它,然后看看我将做什么。谢谢