Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在不等待的情况下调用.NET中的异步函数_C#_.net_Async Await - Fatal编程技术网

C# 如何在不等待的情况下调用.NET中的异步函数

C# 如何在不等待的情况下调用.NET中的异步函数,c#,.net,async-await,C#,.net,Async Await,我在C#中有一个异步函数,如下所示: private static async Task AddEmoji(string emoji) { ... } 我有一种情况,我想打电话给它,但我不想等待它的结果,我不在乎它是否有效。正确的方法是什么?我想我可以在不添加async参数的情况下调用它: AddEmoji(“这不适用于asp.net--asp.net应用程序中不允许使用异步void方法。但是,控制台、WPF、Winforms等应用程序都可以。有关完整讨论,请参阅注释 最好的方法是在异步

我在C#中有一个异步函数,如下所示:

private static async Task AddEmoji(string emoji)
{
   ...
}
我有一种情况,我想打电话给它,但我不想等待它的结果,我不在乎它是否有效。正确的方法是什么?我想我可以在不添加async参数的情况下调用它:


AddEmoji(“这不适用于asp.net--
asp.net应用程序中不允许使用异步void
方法。但是,控制台、WPF、Winforms等应用程序都可以。
有关完整讨论,请参阅注释

最好的方法是在
异步void
方法中等待它

只写
AddEmoji(“在你的Task.Run()中)的问题,wait不在Func中。你通常会在任务本身上等待(把
wait
放在
Task.Run()
之前),但我认为在你的情况下,你可以省略wait以避免等待并忽略结果:

Task.Run(()=>AddEmjoi(“
我不想等待它的结果,我也不在乎它是否有效

这是非常不寻常的;首先要检查的是这样一个假设,即你实际上不需要知道它何时完成(或是否完成),并且你可以默默地忽略所有异常。这也意味着,当你的应用程序退出时,你可以完成这项工作,永远不会完成(同样,你也不会知道,因为异常会被忽略)——记住,在ASP.NET这样的托管场景中,你无法控制你的应用程序何时退出

也就是说,你可以这样做“开火并忘记”:


var=AddEmoji(“你有没有试过在不等待的情况下调用它:Task.Run(()=>AddEmoji)(“这是第二次尝试-你可能需要
Task.Run(async()=>await AddEmoji”)(“如果你不在乎它是否有效,为什么一开始就麻烦调用它?大家好-如果我调用@NikolaBabic或Marc的建议,我会得到一个CS4014(考虑应用“等待”操作员)警告。这并不是说我完全不在乎它是否有效——我只是不想等待它返回或知道它是否有效,因为如果它失败了,我不会特别采取不同的措施。请注意,在.NET 4.5之前将任务放到地板上是一个非常糟糕的主意。如果该任务包含异常,则该任务就是最终任务zer将重播它。这在4.5中被更改。“但它们非常适合于开火和遗忘的情况。”-不,我强烈反对-这是一件非常糟糕的事情,原因是:有框架(包括MVC)在其中被主动阻止-意思是:它会导致异常(由于同步上下文选择不允许)。我在语义上同意你的观点,但实际上:养成这样的习惯真的是一件非常糟糕的事情。如果它今天不咬你,它可能会因为内部框架的更改而在以后意外失败。我不得不重新发布库,因为我正是这样做的。@MarcGravel详细介绍了你所说的“主动阻止”的确切含义“请问?您的意思是捕获的SynchronizationContext不允许继续发布到它吗?这不是我遇到的问题-您是否有来源?当然,在“只需调用它并使用
GC.KeepAlive
来抑制警告”中也存在同样的风险。”您在评论中提倡的方法,因为
AddEmoji
可以在任何时候通过“主动阻止”发回同步上下文,我的意思是:当你这样做的时候,它实际上会抛出一个异常;同步上下文会这样做-在ASP.NET的情况下的错误是-这只发生在调用
异步void
方法时-被引发(当
\u state.AllowVoidAsyncOperations
false
)当您使用
任务调用
GC.KeepAlive
时(将其放在地板上,同时让编译器高兴),它不会触发同步上下文显式查找的
async void
场景(阻止)-因为它现在是一个
异步任务
@marcGravel很有趣。完美,这正是我想要的。谢谢!这是我第一次看到反对
异步void
的真正可靠的论据。我会更新我的答案。这需要一个新的线程池线程来运行
AddEmoji
的第一位,这是不必要的昂贵如果我这样做,et a CS4014(考虑应用“wait”操作符)。它是有效的,但显然这不是最好的做法,因为我得到了警告。所以我想知道什么是“正确的”要做的事情。我也同意@ CangoN7——它看起来像使用任务。运行这里只是创建一个额外的层,我不使用。我经常碰到这种情况。考虑1)一种在无限循环中从流异步读取数据并发布其读取的帧的方法。此方法永远不会返回,但我希望我的应用程序在抛出意外异常时崩溃;2)执行异步操作并具有自己错误处理的
System.Threading.Timer
回调;3)状态机的状态条目处理程序,它执行一些异步工作,并在工作成功或失败时在状态机上激发适当的事件。对于这些情况,我还没有找到比
async void
更好的方法。@canton7:第一个示例不是“激发并忘记”,因为您希望检测错误。第二个示例是
async void
的一个很好的用例-请注意,这是一个事件,这正是为什么
async void
首先被添加到语言中的原因。第三个示例更可疑;在我看来,更好的设计可能是可能的,但即使有了这个示例,您也在谈论它g关于“处理程序”-即逻辑事件,即使它不是文字事件,因此
async void
在那里也是可以接受的。感谢您的回复。很难找到解决这些情况的好方法,在fir中,“
async void
之后永远不应该使用”