当对异步任务使用丢弃(_)时,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(() => 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”时不会传播异常