使用异步vs“旧异步委托”进行即发即弃我试图用一种新语法替换我的旧的“即发即弃”调用,希望更简单,它似乎在逃避我。这是一个例子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();
}}两种方法都做同样的事情,但是我似乎已经获得了(没有必要EndInvoke和关闭处理,这仍然有点争议)我正在以新的方式失去等待a Task.Yield(),这实际上带来了一个新的问题必须重写所有现有的异步F&F方法只是为了添加一个单行。在性能/清理方面是否有一些无形的收获?如果我无法修改背景方法,我将如何应用异步?在我看来,没有直接的方法,我将不得不创建一个等待Task.Run()的包装器异步方法?编辑:我现在看到我可能会错过一个真正的问题。问题是:给定一个同步方法A(),如何使用async/ await以一种即发即忘的方式异步调用它,而不会得到比“旧方式”更复杂的解决方案
3 回答
肥皂起泡泡
TA贡献1829条经验 获得超6个赞
正如其他答案中所述,并且通过这篇优秀的博客文章,您希望避免async void
在UI事件处理程序之外使用。如果你想要一个安全的 “即发即忘” async
方法,请考虑使用这种模式(信用卡@ReedCopsey;这种方法是他在聊天对话中给我的方法):
为
Task
。创建扩展方法。它运行传递Task
和捕获/记录任何异常:static async void FireAndForget(this Task task){ try { await task; } catch (Exception e) { // log errors }}
永远不要在创建时使用
Task
样式async
方法async void
。以这种方式调用这些方法:
MyTaskAsyncMethod().FireAndForget();
你不需要await
它(也不会产生await
警告)。它也会正确处理任何错误,因为这是你放置的唯一地方async void
,你不必记得在try/catch
任何地方放置块。
如果你真的想要它,你还可以选择不使用该async
方法作为“即发即弃”的方法await
。
墨色风雨
TA贡献1853条经验 获得超6个赞
对我来说,似乎“等待”某些东西和“发射并忘记”是两个正交的概念。您可以异步启动方法而不关心结果,或者您希望在操作完成后继续在原始上下文上执行(并且可能使用返回值),这正是await所做的。如果你只想在ThreadPool线程上执行一个方法(这样你的UI不会被阻止),那就去吧
Task.Factory.StartNew(() => DoIt2("Test2"))
你会没事的
- 3 回答
- 0 关注
- 382 浏览
添加回答
举报
0/150
提交
取消