c# - async/await 方法中的耗时任务

标签 c# .net multithreading performance async-await

与线程相比,我不太了解 async/await 的好处。

在方法内部的情况下,我有一个没有异步/等待版本的操作在其他异步操作中间消耗一些时间,例如 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。避免浪费时间的最佳做法是什么?

最佳答案

不,不一定。如果您从单线程的 SynchronizationContext 调用 Start 方法(比如任何 UI 上下文,如 WindowsFormsSynchronizationContext 或 DispatcherSynchronizationContext),答案是肯定的 [*]。

如果您从其他线程(比如工作线程)调用Start。它不会占用 20 毫秒 x 1000。因为await之后的代码会在ThreadPool thread中执行在这种情况下。所以可以有 N 个线程在 await 之后执行代码。在您的情况下,N 将小于或等于 500。

就是说,您不应该在异步方法中阻塞。如果您需要在异步方法中使用任何同步代码,您应该使用 await Task.Run(()=> CodeThatBlocks())

* 如果 SynchronizationContext 没有被 SynchronizationContext.SetSynchronizationContext 覆盖

关于c# - async/await 方法中的耗时任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25699216/

相关文章:

c# - 无法在 ASP.Net MVC 5 中找到区域 View

.net - (为什么)我应该使用混淆?

c# - .NET 中的多线程绘图?

java - BlockingQueues 和线程访问顺序

java - java中多线程的机制

c# - 在 C# 中清理永久线程的正确方法

C# 方法重载与接口(interface)参数

C# 调整大小的图像有黑色边框

c# - 在 C# 中使用超时更改按钮的文本

c# - 有效文件名的正则表达式模式