c# - 优化异步HttpClient请求

标签 c# .net multithreading asynchronous

我创建了一个类来处理多个 HTTP GET 请求。它看起来像这样:

public partial class MyHttpClass : IDisposable
{
    private HttpClient theClient;
    private string ApiBaseUrl = "https://example.com/";

    public MyHttpClass()
    {

        this.theClient = new HttpClient();
        this.theClient.BaseAddress = new Uri(ApiBaseUrl);
        this.theClient.DefaultRequestHeaders.Accept.Clear();
        this.theClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    }

    public async Task<JObject> GetAsync(string reqUrl)
    {

        var returnObj = new JObject();
        var response = await this.theClient.GetAsync(reqUrl);

        if (response.IsSuccessStatusCode)
        {
            returnObj = await response.Content.ReadAsAsync<JObject>();
            Console.WriteLine("GET successful");

        }
        else
        {
            Console.WriteLine("GET failed");
        }

        return returnObj;
    }
    public void Dispose()
    {
        theClient.Dispose();
    }
}

然后,我通过在 Task.Run() 上使用循环,然后在 Task.WaitAll() 之后以以下方式对多个请求进行排队:

public async Task Start()
{
    foreach(var item in list)
    {
        taskList.Add(Task.Run(() => this.GetThing(item)));
    }
    Task.WaitAll(taskList.ToArray());
}

public async Task GetThing(string url)
{
    var response = await this.theClient.GetAsync(url);

    // some code to process and save response

}

它的工作速度肯定比同步操作快,但没有我预期的那么快。根据其他建议,我认为本地线程池正在减慢我的速度。 MSDN 建议我应该将其指定为长时间运行的任务,但我找不到像这样调用它的方法。

现在我还没有限制线程,我只是进行批量处理和测试速度以发现正确的方法。

有人能给我建议一些可以提高速度的领域吗?

最佳答案

所以,在您设置 DefaultConnectionLimit 后一个很好的高数字,或者只是管理与您正在访问的主机的连接的 ServicePoint 的 ConnectionLimit:

ServicePointManager
    .FindServicePoint(new Uri("https://example.com/"))
    .ConnectionLimit = 1000;

唯一可疑的代码是你开始一切的地方......

public async Task Start()
{
    foreach(var item in list)
    {
        taskList.Add(Task.Run(() => this.GetThing(item)));
    }
    Task.WaitAll(taskList.ToArray());
}

这可以减少到

var tasks = list.Select(this.GetThing);

创建任务(您的异步方法返回热(运行)任务...无需使用Task.Run双重换行)

然后,不要在等待它们完成时阻塞,而是异步等待:

await Task.WhenAll(tasks);

关于c# - 优化异步HttpClient请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30158008/

相关文章:

c# - 你可以用什么不同的方式来写这个

c# - 向 Entity Framework 中的表添加虚拟列?

c# - 将 SecureString 与 LogonUser 一起使用

c# - 如何调试 .NET Framework 源代码

java - 最后返回 "happen after"吗?

java - 这个多线程 Java 代码是如何工作的?

c# - 如何找到两个地方之间的位置?

c# - 将 Int 数组转换为枚举标志

asp.net - Internet Explorer 11 在 PageRequestManager.js 中出现脚本错误

Java Thread.sleep 比预定时间早 "much"醒来