当对异步任务使用丢弃(_)时,try catch 不会捕获被调用方法的内部异常[重复]

Posted

技术标签:

【中文标题】当对异步任务使用丢弃(_)时,try catch 不会捕获被调用方法的内部异常[重复]【英文标题】:When using discard (_) to an async task the try catch does not catch the inner exception of the called method [duplicate] 【发布时间】:2022-01-03 18:57:00 【问题描述】:

我在一个 .net 框架项目 MVC 上工作,目前我面临以下问题。

我有一个 api

[HttpGet]
[ActionName("testme")]
public async Task<bool> TestMe()

  await AddNoteAsync("Test");
  return true;

AddNoteAsync 是:

public static async Task AddNoteAsync(string note)

  try
    var client = new Client()              
    await client.Note.CreateAsync(note);    
  
  catch (Exception)
                 
   // ignored
  

当 CreateAsync() 出现异常时,这可以正常工作

当我想丢弃 AddNoteAsync 时,问题就来了:

[HttpGet]
[ActionName("testme")]
public bool TestMe()

  _ = AddNoteAsync("Test");
  return true;

这个最终会回来的

"System.AggregateException 未观察到任务的异常 通过等待任务或访问其异常属性。作为 结果,未观察到的异常被终结器重新抛出 线程。”

即使我在 AddNoteAsync 中等待。

如何修改代码以免出现聚合异常?

【问题讨论】:

你为什么切换到丢弃?你认为它会改变什么?而且您已经知道如何修改代码以避免错误 - 回滚您的更改。 这与丢弃变量无关,与您有关的一切也删除await。这把它变成了一劳永逸的事情。你可以做var task = AddNoteAsync(.. 并得到相同的结果。把 await 放回去。 @Damien_The_Unbeliever,问题是 AddNoteAsync 是后面几个步骤的一部分,我不想等待它,因为它只是通知某人。我不明白最好的方法是等待,但我想知道是否有另一种方法可以触发并忘记它 根据David Fowler et. al.'s async guidance,您的代码应该可以按预期工作。您是否尝试过使用 Task.Run(() =&gt; AddNoteAsync("Test")) 代替? 您的服务范围将在您的控制器操作完成后被释放。这可能会破坏您的工作并忘记任务。您可能希望将这些任务排队并在BackgroundService 中处理它们。 【参考方案1】:

使用此代码:

[HttpGet]
[ActionName("testme")]
public bool TestMe()

  _ = AddNoteAsync("Test");
  return true;

您正在调用一个潜在的异步方法。

如果方法没有完成,TestMe会立即返回,不会捕获异常。

你可以看到AddNoteAsync这两个版本的区别:

async Task AddNoteAsync1(string s)

    throw new Exception("BOOM!");

async Task AddNoteAsync2(string s)

    await Task.Delay(10000);
    throw new Exception("BOOM!");

``

【讨论】:

以上是关于当对异步任务使用丢弃(_)时,try catch 不会捕获被调用方法的内部异常[重复]的主要内容,如果未能解决你的问题,请参考以下文章

SqlDataReader 和 T-SQL:在使用来自 C# 的“异步”调用时使用“try...catch”和“throw”时不会传播异常

C#_异步编程走进异步编程的世界 - 剖析异步方法(下)

如何在 JS 中使用 try、catch、.then 链接和异步等待来解决承诺?

为啥使用Try,Catch捕获异常,程序依然Crash

try..catch 没有捕捉到异步/等待错误

有没有办法将等待/异步 try/catch 块包装到每个函数?