【发布时间】:2012-10-09 15:04:31
【问题描述】:
我正在尝试用一种新语法替换我旧的即发即弃调用,希望更简单,但它似乎让我望而却步。这是一个例子
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 并关闭句柄,这仍然有点值得商榷)我不得不等待@987654324 以新的方式失败@,这实际上带来了一个新问题,即必须重写所有现有的异步 F&F 方法才能添加该单行。在性能/清理方面是否有一些看不见的收益?
如果我无法修改后台方法,我将如何应用异步?在我看来,没有直接的方法,我必须创建一个等待 Task.Run() 的包装异步方法?
编辑:我现在看到我可能错过了一个真正的问题。问题是:给定一个同步方法 A(),我如何才能使用async/await 以即发即弃的方式异步调用它,而不会得到比“旧方法”更复杂的解决方案
【问题讨论】:
-
async/await 并不是真正为将同步工作负载卸载到另一个线程而设计的。我在一些非常庞大的项目中使用了 async/await,但看不到
Thread.Yield。我认为这段代码滥用了异步等待哲学。如果没有异步 IO,async/await 可能是错误的解决方案。 -
我不同意,尤其是在我的情况下;没有合理的理由强制 http 请求者等待一个完整的过程完成以在一开始就接收可用的响应。其余的可以安全卸载。真正唯一的问题是 async/await 是否可以帮助,使情况变得更糟,或者在这种情况下无法使用。我必须承认我对它是什么有不同的想法。
-
我不同意这项工作可能需要卸载。我是说使用
async/await结合Task.Yield有难闻的气味。在这里使用ThreadPool.QueueUserWorkItem会更合适。毕竟,这确实是您想要做的......将工作发送到 ThreadPool 并使用相当少的代码占用空间,对吧? -
哦,好的。公平的评论,我误解了你的说法。我想我只是认为使用异步我只会调用一个方法,它会神奇地从另一个线程开始:)。说到不同的方法,有人知道这三者之间的比较吗?
ThreadPool.QueueUserWorkItemvsTask.Factory.StartNewvsdelegate.BeginInvoke?如果我要做出改变,我不妨以最好的方式去做。 -
这能回答你的问题吗? Fire and forget async method in asp.net mvc
标签: c# asynchronous c#-5.0