Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.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# 从ContinueWith引发异常_C#_Visual Studio 2010_Task Parallel Library - Fatal编程技术网

C# 从ContinueWith引发异常

C# 从ContinueWith引发异常,c#,visual-studio-2010,task-parallel-library,C#,Visual Studio 2010,Task Parallel Library,我正在尝试使用ContinueWith()包装异步任务可能引发的异常。如果我只是从continuation操作中抛出,事情似乎是可行的,但是我的调试器声明异常未处理。我是做错了什么,还是这是Visual Studio的问题?有没有一种更干净的方法来实现这一点,或者有没有一种方法可以绕过我的调试器停止处理最终被处理的异常 下面的测试通过并打印“捕获到预期的包装异常”,但当我调试它时,throw new CustomException行显示为“unhandled by user code” 您似乎不

我正在尝试使用
ContinueWith()
包装异步任务可能引发的异常。如果我只是从continuation操作中抛出,事情似乎是可行的,但是我的调试器声明异常未处理。我是做错了什么,还是这是Visual Studio的问题?有没有一种更干净的方法来实现这一点,或者有没有一种方法可以绕过我的调试器停止处理最终被处理的异常

下面的测试通过并打印“捕获到预期的包装异常”,但当我调试它时,
throw new CustomException
行显示为“unhandled by user code”

您似乎不是在用一个延续“包装”异常,而是在延续中抛出异常。如果DoWorkAsync可以引发异常,我会将其“包装”到一个continuation中,如下所示:

DoWorkAsync().ContinueWith(t=>{
 Console.WriteLine("Error occurred: " + t.Exception);
}, TaskContinuationOptions.OnlyOnFaulted);
或者,如果要在异步方法之外“处理”异常,可以执行以下操作:

var task = DoWorkAsync();

task.Wait();
if(task.Exception != null)
{
  Console.WriteLine("Error occurred: " + task.Exception);
}
如果要转换抛出的异常,可以执行以下操作:

var task = DoWorkAsync().ContinueWith(t=>{
 if(t.Exception.InnerExceptions[0].GetType() == typeof(TimeoutException))
 {
     throw new BackoffException(t.Exception.InnerExceptions[0]);
 }
}, TaskContinuationOptions.OnlyOnFaulted);
if(task.IsFaulted)
{
   Console.WriteLine(task.Exception.InnerExceptions[0]);
   // TODO: check what type and do something other than WriteLine.
}
您可以这样处理
BackoffException

var task = DoWorkAsync().ContinueWith(t=>{
 if(t.Exception.InnerExceptions[0].GetType() == typeof(TimeoutException))
 {
     throw new BackoffException(t.Exception.InnerExceptions[0]);
 }
}, TaskContinuationOptions.OnlyOnFaulted);
if(task.IsFaulted)
{
   Console.WriteLine(task.Exception.InnerExceptions[0]);
   // TODO: check what type and do something other than WriteLine.
}
当启用“仅我的代码”时,Visual Studio在某些情况下会在引发异常的行上中断,并显示一条错误消息,上面显示“异常未由用户代码处理”。此错误是良性的。您可以按F5继续并查看这些示例中演示的异常处理行为。为了防止VisualStudio在第一个错误时出错,只需取消选中工具、选项、调试、常规下的“仅我的代码”复选框


这里的关键是您必须访问Exception属性(或者通过访问Task.Result属性(如果您有任务)在AggregateException中重新引发异常)…DoWorkAsync()可以引发一系列不同的异常,我只是尝试将它们转换为几个更高级别的“CustomException”这样在调用代码中处理起来就不那么麻烦了。我现在实际上不知道如何完全处理这些事情。所以我想把一个失败的任务转换成另一个失败的任务,其中异常的类型不同。如果你抛出一个CustomException,TPL子系统将把它封装在与w相同的AggregateException类型中我们将包装从DoWorkAsync引发的异常。也就是说,如果“CustomException”所做的只是聚合和AggregateException,那么我看不到它的好处……DoWorkAsync()的真实版本可以抛出DataServiceRequestException、DataServiceClientException、TimeoutException等。在这些异常对象的不同位置,是指示错误类型的状态代码(HTTP代码:400、503等)。因此,在这一连续过程中,我想将其转换为类似BackoffException(int-retryAfterSeconds)的内容和DatastoreCommException,所以当我在代码中使用更高层的数据存储时,我的异常处理就简单多了。