我在C#中具有如下异步功能:
private static async Task AddEmoji(string emoji)
{
...
}
在某些情况下,我想调用它,但是我不想等待它的结果,并且我不在乎它是否有效。解决这个问题的正确方法是什么?我以为可以不添加async参数就可以调用它:
AddEmoji("");
...可以,但是VS给了我CS4014编译警告,所以我猜这是不对的。然后,我尝试为其创建一个任务:
Task.Run(() => await AddEmoji(""));
但这给了我一个实际的编译错误:
错误CS4034'await'运算符只能在异步中使用 lambda表达式。考虑使用标记该Lambda表达式 “异步”修饰符。
解决这个问题的正确方法是什么?
答案 0 :(得分:0)
在Task.Run()中,等待不会进入Func <>内部。您通常会在Task本身上等待(将await
放在Task.Run()
之前),但是我认为在您的情况下,您可以省略await以便不等待并忽略结果:
Task.Run(() => AddEmjoi(""))
答案 1 :(得分:0)
我不想等待其结果,也不在乎它是否有效。
极端与众不同;首先要检查的是这种假设,即您实际上不需要知道它何时完成(或 if 它完成),并且可以无声地忽略所有异常。这也意味着,当您的应用退出时,您可以永不完成这项工作(并且再次,您将不会知道,因为会忽略异常)-请记住,在诸如ASP.NET的托管方案中,您在您的应用退出时不受控制。
也就是说,您可以这样“抛弃”:
var _ = AddEmoji("");
答案 2 :(得分:-3)
这不适用于asp.net-asp.net应用程序中不允许使用async void
方法。控制台,WPF,Winforms等应用程序也可以。请参阅注释以获取完整的讨论。
最好的方法是在await
方法内async void
。
仅写AddEmoji("");
的问题是:如果失败,会发生什么?如果在AddEmoji
中引发了异常,则该异常将捆绑在Task
返回的AddEmoji
中。但是,由于您丢掉了Task
,所以您永远不会知道。因此AddEmoji
可能会以失败的方式失败,但是您永远不会知道。这就是为什么编译器给您一个错误。
但是,async void
方法避免了这种情况。如果在async void
方法中引发了异常,则该异常将重新引发到ThreadPool上,这将导致您的应用程序崩溃。您肯定会知道出了什么问题!
人们建议不要使用async void
方法,但是它们非常适合一劳永逸的情况。这些建议源于人们在想知道何时完成操作时尝试使用async void
方法的人。
public async void AddEmojiImpl(string emoji) => await AddEmoji(emoji);
或
public async void AddEmojiImpl(string emoji)
{
try
{
await AddEmojiImpl(emoji);
}
catch (EmojiAddException e)
{
// ...
}
}
本地功能对此特别有用。