3

假设我有一个带有 Main 方法的控制台应用程序,如下所示:

public static void Main(string[] args)
{
    AppDomain.CurrentDomain.UnhandledException += (sender, eventArgs) =>
    {
        Console.WriteLine("App Unobserved");
    };
    TaskScheduler.UnobservedTaskException += (sender, eventArgs) =>
    {
        Console.WriteLine("Task Unobserved");
    };
    Task.Run(async () => await MyAwesomeMethod());
    // other awesome code...
    Console.ReadLine();
}

public static async Task MyAwesomeMethod()
{
    // some useful work
    if (something_went_wrong)
        throw new Exception();
    // other some useful work
}

所以,我只是运行 MyAwesomeMethod(即发即弃),并想做一些其他工作,但我也想知道是否有任何未处理的异常。但是应用程序成功完成,没有任何问题迹象(只是吞下了异常)。

如何在不等待或使用 Task.Run(...).Wait() 的情况下处理来自 MyAwesomeMethod() 的异常?

4

4 回答 4

2

所以,我只是运行 MyAwesomeMethod(即发即弃)......但我也想知道是否有任何未处理的异常。但是应用程序成功完成,没有任何问题迹象(只是吞下了异常)。

那不是“一劳永逸”。“一劳永逸”的字面意思是您不在乎任务何时(或是否)完成(或错误)。

如何在不等待或使用 Task.Run(...).Wait() 的情况下处理来自 MyAwesomeMethod() 的异常?

await无论如何使用:

Task.Run(async () => {
  try {
    await MyAwesomeMethod();
  } catch (Exception ex) {
    Console.WriteLine(ex);
  }
});
于 2017-08-09T19:20:58.417 回答
1

完成后,您可以检查任务的状态

Task.Run(() => MyAwesomeMethod()).ContinueWith((task) =>
{
    if (task.Status == TaskStatus.RanToCompletion && task.Result != null)
    {

    }
    else
    {
        try
        {
            Logger.LogError(task.Exception.ToString());
            Logger.LogMessage("something_went_wrong");
        }
        catch { }
    }
});
于 2017-08-07T18:01:56.430 回答
0

例如,您可以将后台任务中的代码包装在 try...catch 块中,并在您进入 catch 块时立即引发事件(如果您这样做的话)。

喜欢

event EventHandler<Exception> exceptionInWorker;

并在任务中

try
{
    //do something
}
catch (Exception e)
{
    exceptionInWorker?.Invoke(this, e);
}
于 2017-08-07T17:56:49.417 回答
-2

您可以像您一样订阅 TaskScheduler.UnobservedTaskException 事件,但使用将 UnobservedTaskExceptionEventArgs 作为其第二个参数的处理程序,通过它您可以通过其 Exception 属性访问未处理的异常并记录有关它的所有信息。

于 2017-08-07T18:16:51.887 回答