mmi*_*mix 58 c# asynchronous c#-5.0
我试图用一种新的语法替换我的旧的"即发即忘"调用,希望更简单,它似乎在逃避我.这是一个例子
class Program
{
static void DoIt(string entry)
{
Console.WriteLine("Message: " + entry);
}
static async void DoIt2(string entry)
{
await Task.Yield();
Console.WriteLine("Message2: " + entry);
}
static void Main(string[] args)
{
// old way
Action<string> async = DoIt;
async.BeginInvoke("Test", ar => { async.EndInvoke(ar); ar.AsyncWaitHandle.Close(); }, null);
Console.WriteLine("old-way main thread invoker finished");
// new way
DoIt2("Test2");
Console.WriteLine("new-way main thread invoker finished");
Console.ReadLine();
}
}
Run Code Online (Sandbox Code Playgroud)
两种方法都做同样的事情,但是我似乎已经获得了(没有必要EndInvoke和关闭处理,这仍然有点争议)我正在以新的方式失去等待a Task.Yield(),这实际上带来了一个新的问题必须重写所有现有的异步F&F方法只是为了添加一个单行.在性能/清理方面是否有一些无形的收获?
如果我无法修改背景方法,我将如何应用异步?在我看来,没有直接的方法,我将不得不创建一个等待Task.Run()的包装器异步方法?
编辑:我现在看到我可能会错过一个真正的问题.问题是:给定一个同步方法A(),如何使用async/ await以一种即发即忘的方式异步调用它,而不会得到比"旧方式"更复杂的解决方案
Ste*_*ary 84
避免async void.它有关于错误处理的棘手语义; 我知道有些人称之为"火与忘记",但我通常使用"火灾和崩溃"这个短语.
问题是:给定一个同步方法A(),如何使用async/await以一种即发即忘的方式异步调用它,而不会得到比"旧方法"更复杂的解决方案
你不需要async/ await.只需将其称为:
Task.Run(A);
Run Code Online (Sandbox Code Playgroud)
Bra*_*NET 51
正如其他答案中所述,并且通过这篇优秀的博客文章,您希望避免async void在UI事件处理程序之外使用.如果你想要一个安全的 "即发即忘" async方法,请考虑使用这种模式(信用卡@ReedCopsey;这种方法是他在聊天对话中给我的方法):
为Task.创建扩展方法.它运行传递Task和捕获/记录任何异常:
static async void FireAndForget(this Task task)
{
try
{
await task;
}
catch (Exception e)
{
// log errors
}
}
Run Code Online (Sandbox Code Playgroud)永远不要在创建时使用Task样式async方法async void.
以这种方式调用这些方法:
MyTaskAsyncMethod().FireAndForget();
Run Code Online (Sandbox Code Playgroud)你不需要await它(也不会产生await警告).它也会正确处理任何错误,因为这是你放置的唯一地方async void,你不必记得在try/catch任何地方放置块.
如果你真的想要它,你还可以选择不使用该async方法作为"即发即弃"的方法await.
Dan*_*ber 18
对我来说,似乎"等待"某些东西和"发射并忘记"是两个正交的概念.您可以异步启动方法而不关心结果,或者您希望在操作完成后继续在原始上下文上执行(并且可能使用返回值),这正是await所做的.如果你只想在ThreadPool线程上执行一个方法(这样你的UI就不会被阻止),那就去吧
Task.Factory.StartNew(() => DoIt2("Test2"))
Run Code Online (Sandbox Code Playgroud)
你会没事的
| 归档时间: |
|
| 查看次数: |
41947 次 |
| 最近记录: |