【发布时间】:2014-09-06 10:16:43
【问题描述】:
与线程相比,我不太了解异步/等待的好处。
如果在一个方法内部,我有一个没有异步/等待版本的操作,它在其他异步操作中间消耗了一些时间,比如 20 毫秒。
调用此方法 1000 次,由于 async/await 仅在一个线程内执行,因此在我的测试中至少会消耗 20ms x 1000 次(使用 Thread.Sleep 进行模拟)。
对 async/await 有什么误解吗?
public void Start()
{
Task[] task = new Task[500];
for (int i = 0; i < 500; i++)
{
task[i] = AsyncGet();
}
await Task.WhenAll(task);
}
public async Task<bool> AsyncGet()
{
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("http://www.example.com");
req.Method = "GET";
using(HttpWebResponse res = (HttpWebResponse)await req.GetResponseAsync())
{
Thread.Sleep(20);//Simulate an operation without async/await version that consume a little bit time
using (Stream responseStream = res.GetResponseStream())
{
StreamReader sr = new StreamReader(responseStream, Encoding.ASCII);
string resp = await sr.ReadToEndAsync();
}
}
}
更新问题:
如果我需要在使用外部库获得 http 响应后进行一些非异步/等待操作,例如操作 json。避免浪费时间的最佳做法是什么?
【问题讨论】:
-
为什么只有 1 个线程,它使用线程池中的任何可用线程。
-
你通常会尽量避免非异步的持久操作。或者,如果同步上下文无关紧要,您可以在返回的
Task对象上使用ConfigureAwait(false)让继续在任何上下文上继续。 -
@eranotzap 发布的代码在 1 个线程上运行。
GetResponseAsync可能在内部使用另一个线程,但鉴于这是一个 IO 操作,他们更有可能使用类似 IO 完成端口之类的东西。 -
我写评论时没有代码。
-
@Dirk 看起来像 Sriram 在下面的回答。回调可能发生在线程池中的多个线程上。
标签: c# .net multithreading performance async-await