与线程相比,我不太理解异步/等待好处。
如果在一个方法中,我有一个没有异步/等待版本的操作,该操作需要花费一些时间,比如在其他异步操作的中间使用20 an。
调用此方法1000次,因为异步/等待只在一个线程内执行,因此在我的测试中它将至少包含20 my x 1000次(使用Thread.Sleep进行模拟)。
对异步/等待有什么误解吗?
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。避免浪费时间的最佳做法是什么?
发布于 2014-09-06 10:32:18
对异步/等待有什么误解吗?
是的,你好像有误会。您不能用async-await来模拟Thread.Sleep行为,因为Thread.Sleep是一个阻塞调用。当您使用await Task.WhenAll时,多个异步请求将并发执行,而不考虑底层线程。
如果您想同时卸载多个请求,使用await Task.Delay测试它们,您将注意到行为上的变化。
您可以更进一步,在调用ConfigureAwait(false)时使用GetResponseAsync,这样您的方法的继续就不会回送回原来的SynchronizationContext (这在处理自定义SynchronizationContext(如WinFormSynchronizationContext)时很重要),并在IOCP上继续执行。
发布于 2014-09-06 10:30:26
无论任何异步/等待结构,休眠线程仍然会休眠线程。异步/等待的思想是尽可能地保持每个线程的占用,以避免创建大量的线程,只需等待I/O。在后台执行CPU密集型操作仍然需要您创建线程。
换句话说,您提供的示例将导致线程冻结20 ms,因为它不是异步/等待的预期用例。
换句话说,要么是:
https://stackoverflow.com/questions/25699216
复制相似问题