如何在异步任务中使VS中断exception,而不会破坏所有exception?

如此处和此处所示 ,异步任务中发生的exception在技术上并非未处理。

在使用MVC时,这尤其令人讨厌。 它实际上花了我们一段时间来弄清楚它为什么越来越多地发生exception没有被捕获,我们在过去几周逐渐向我们的应用程序引入了Web API调用。

public async Task Foo() { // ... } 

建议的解决方法是使VS中断所有exception而不是仅处理未处理的exception。 它有效,令人讨厌的“副作用”,确实在所有exception情况下都会破坏:)

是否有其他解决方法不涉及打破所有exception? 它可以特定于MVC但不一定是(意味着它是一个适用于MVC的通用解决方案)。

A)包装您的调用并在您的任务代码中抛出自定义exception。 打破你的自定义exception。 您可以选择第一次抛出的例外。

B)。 如果你有任何等待代码,Debug.Assert()你的任务结果。 即,不只是射击和遗忘。 如果您在某个位置等待它们,或者在延续中粘贴error handling,则任务会返回属性中的exception。

伪代码即任务。 continuewith(r => if(!r.Exception为null)Debug.Break()))等。

希望能帮助您走上正确的道路。

如果此处没有其他工作,您可以尝试收听此事件

 AppDomain.CurrentDomain.UnhandledException 

要么

 AppDomain.CurrentDomain.FirstChanceException 

然后你需要放一些if-constructs(例如检查发送者),只有在它有意义时才能点击你的断点。

MSDN中的try-catch引用提供了有关异步方法中的exception的一些指导和示例,并指出:“应用await的已完成任务可能处于故障状态,因为返回任务的方法中存在未处理的exception。等待任务抛出一个exception。“

对于该页面上给出的示例,它指出:“以下示例说明了异步方法的exception处理。要捕获异步任务抛出的exception,请将await表达式放在try块中,并在catch块中捕获exception。取消注释示例中throw new Exception行以演示exception处理。任务的IsFaulted属性设置为True ,任务的Exception.InnerException属性设置为exception,exception将在catch块中捕获

这是给出的示例中的副本:

 public async Task DoSomethingAsync() { Task theTask = DelayAsync(); try { string result = await theTask; Debug.WriteLine("Result: " + result); } catch (Exception ex) { Debug.WriteLine("Exception Message: " + ex.Message); } Debug.WriteLine("Task IsCanceled: " + theTask.IsCanceled); Debug.WriteLine("Task IsFaulted: " + theTask.IsFaulted); if (theTask.Exception != null) { Debug.WriteLine("Task Exception Message: " + theTask.Exception.Message); Debug.WriteLine("Task Inner Exception Message: " + theTask.Exception.InnerException.Message); } } private async Task DelayAsync() { await Task.Delay(100); // Uncomment each of the following lines to // demonstrate exception handling. //throw new OperationCanceledException("canceled"); //throw new Exception("Something happened."); return "Done"; } // Output when no exception is thrown in the awaited method: // Result: Done // Task IsCanceled: False // Task IsFaulted: False // Output when an Exception is thrown in the awaited method: // Exception Message: Something happened. // Task IsCanceled: False // Task IsFaulted: True // Task Exception Message: One or more errors occurred. // Task Inner Exception Message: Something happened. // Output when a OperationCanceledException or TaskCanceledException // is thrown in the awaited method: // Exception Message: canceled // Task IsCanceled: True // Task IsFaulted: False 

如此处所示,启用“Just My Code”是实现此目的的一种方法。 确实,这些exception在技术上并不是未处理的,但它们未被用户代码处理 ,这使得VS能够执行有用的操作并向您显示exception发生的位置。

有关截图,请参阅此答案 。

显然,此设置还有其他含义(例如,您不能再单步执行框架代码),因此这可能适用也可能不适用。

您可以为TaskScheduler.UnobservedTaskException添加处理程序。

但是,您可能已经尝试过这种方法,并希望有一种方法可以使调试器在原始exception中中断,而不是在未观察到的任务exception处理程序中。