c# - 同步并发 HttpClient 使用

标签 c# asynchronous concurrency c#-5.0 dotnet-httpclient

我正在尝试同步使用 HttpClient,但是当我发出许多并发请求时它停止工作。我写了两个测试,一个用于异步使用,一个用于同步使用。 TestMethod总是在 4 秒后返回响应。异步测试工作正常。在同步测试中几乎所有请求都超时,最后只有约 20 个请求成功。我都尝试使用一个 HttpClient用于请求和创建新的 HttpClient每个新请求的实例。没有不同。也许与this deadlock有关.

我将 VS2013 与 .NET Framework 4.5.1 一起使用,目标是 Framework 4.5。我通过 NuGet 获取 HttpClient:<package id="Microsoft.Net.Http" version="2.2.15" targetFramework="net45" />

我不想使用 HttpClient异步,因为这意味着我必须重写我的整个应用程序。知道我在这里做错了什么吗?

// all 800 requests complete successfully
[Test]
public async void Asyncmethod()
{
    var sw = new Stopwatch();
    sw.Start();

    var client = new HttpClient();
    client.Timeout = TimeSpan.FromSeconds(15);

    var tasks = Enumerable.Range(0, 800).Select(x => Task.Run(async () =>
    {
        try
        {
            var swx = new Stopwatch();
            swx.Start();
            var response = await client.GetStringAsync("http://localhost:7002/TestMethod").ConfigureAwait(false);
            swx.Stop();
            Console.WriteLine(x + " " + response + " in " + swx.ElapsedMilliseconds + " ms.");
        }
        catch (Exception e)
        {
            Console.WriteLine(x + " Exception: " + e.Message);
        }
    })).ToArray();

    await Task.WhenAll(tasks);

    sw.Stop();
    Console.WriteLine(sw.ElapsedMilliseconds);
}

// almost all of 800 requests time out
[Test]
public void Syncmethod()
{
    var sw = new Stopwatch();
    sw.Start();

    var client = new HttpClient();

    var tasks = Enumerable.Range(0, 800).Select(x => Task.Run(() =>
    {
        try
        {
            var swx = new Stopwatch();
            swx.Start();
            var response = client.GetStringAsync("http://localhost:7002/TestMethod");
            if (response.Wait(15000))
            {
                swx.Stop();
                Console.WriteLine(x + " " + response.Result + " in " + swx.ElapsedMilliseconds + " ms.");
            }
            else
            {
                swx.Stop();
                Console.WriteLine(x + " timed out.");
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(x + " Exception: " + e.Message);
        }
    })).ToArray();

    foreach (var task in tasks)
        task.Wait(60000);

    sw.Stop();
    Console.WriteLine(sw.ElapsedMilliseconds);
}

最佳答案

我确实建议您对 HttpClient 使用 await 而不是 Wait。如果您确实需要同步请求,请考虑使用支持同步方法的 WebClient

也就是说,我相信您看到该行为的原因是 ServicePointManager.DefaultConnectionLimit,它将限制对给定服务器的请求数量。如果您希望同一台服务器有大量并发请求(同步 异步),则需要增加该限制(UI 应用程序默认为 2 个)。

关于c# - 同步并发 HttpClient 使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19509283/

相关文章:

c# - 如何将两个字符串(日期和时间)合并为一个 DateTime

c# - .NET 核心 Web API key

c# - 在保持排序的同时将有序列表保存到数据库的最佳方法

python - 委托(delegate)给异步子生成器

scala - Erlang 并发模型 vs Scala vs Go

multithreading - Akka - 调度员

concurrency - F# 中多个线程之间的共享列表/映射?

c# - 具有后备属性的列表没有获得附加值

ios - NSURLConnection 和 sendAsynchronousRequest :queue:completionHandler: - does the completion block run in the main thread

java - 如何针对特定场景正确使用Apache Camel?