首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >异步/等待方法中的耗时任务

异步/等待方法中的耗时任务
EN

Stack Overflow用户
提问于 2014-09-06 10:16:43
回答 2查看 1.5K关注 0票数 2

与线程相比,我不太理解异步/等待好处。

如果在一个方法中,我有一个没有异步/等待版本的操作,该操作需要花费一些时间,比如在其他异步操作的中间使用20 an。

调用此方法1000次,因为异步/等待只在一个线程内执行,因此在我的测试中它将至少包含20 my x 1000次(使用Thread.Sleep进行模拟)。

对异步/等待有什么误解吗?

代码语言:javascript
复制
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。避免浪费时间的最佳做法是什么?

EN

回答 2

Stack Overflow用户

发布于 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上继续执行。

票数 2
EN

Stack Overflow用户

发布于 2014-09-06 10:30:26

无论任何异步/等待结构,休眠线程仍然会休眠线程。异步/等待的思想是尽可能地保持每个线程的占用,以避免创建大量的线程,只需等待I/O。在后台执行CPU密集型操作仍然需要您创建线程。

换句话说,您提供的示例将导致线程冻结20 ms,因为它不是异步/等待的预期用例。

换句话说,要么是:

  • 只需使用异步I/O。不要进行任何CPU密集型处理(也不要使用睡眠)。
  • 使用线程池。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25699216

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档