【问题标题】:Multiple Requests Using Task.WhenAll()使用 Task.WhenAll() 的多个请求
【发布时间】:2019-11-26 17:07:34
【问题描述】:

我正在尝试对上传到 Azure 的 WebApi 进行压力测试。具体来说,此测试用于登录应用程序。我决定使用 c# 制作一个模拟客户端并创建一个任务列表,每个任务都会向我的 WebApi 发送相同的请求。我的问题是它在使用超过 300 个任务后抛出异常。

异常:“线程已被取消”
内部异常:“对象引用未设置为对象的实例。” 发生异常的代码:await (Task.WhenAll(tasks));

我在测试代码中做错了吗?如果是这样,是什么?以及如何纠正错误?谢谢!

注意事项: -我已经尝试在本地针对 API 运行测试代码

-API 代码被一个 try catch 块包围,当针对它运行测试代码时,它没有命中我在 catch 块中设置的断点,并且测试代码中仍然抛出异常。

-由于这是一个工作中的项目,我已将真实登录凭据和 API 的 URL 替换为替身

下面是我的测试代码

public static async Task<decimal> LoginTestParallel3Async(){
    Stopwatch timer = new Stopwatch();
    var tasks = new List<Task>();
    LoginRequestModel request = new LoginRequestModel();

    int numOfRequests = 500;

    decimal totalTimeForTasks = 0;
    string jsonObject = "";

    request.UserName = "User";
    request.Password = "Password";
    request.UserId = 0;

    jsonObject = Newtonsoft.Json.JsonConvert.SerializeObject(request);

    try
    {
        using (var client = new HttpClient())
        {
            for (int i = 0; i < numOfRequests; i++)
            {
                //tasks.Add(client.PostAsync("URLForAzure", new StringContent(jsonObject, Encoding.UTF8, "application/json")));
                tasks.Add(client.PostAsync("URLForLocal", new StringContent(jsonObject, Encoding.UTF8, "application/json")));
            }

            timer.Start();
            await (Task.WhenAll(tasks));
            timer.Stop();
            totalTimeForTasks = timer.ElapsedMilliseconds;

            Console.WriteLine("total time for request: " + totalTimeForTasks + " milliseconds");
            Console.ReadLine();
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message.ToString());
        return totalTimeForTasks;
    }

    return totalTimeForTasks;
}

【问题讨论】:

    标签: c# performance-testing


    【解决方案1】:

    根据文档,HttpClient 中的 MaxConnectionsPerServer 属性的值默认为 256。所以为了达到你所需要的,你必须把这个值改成更大的数字。

    https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclienthandler.maxconnectionsperserver?view=netcore-2.0#System_Net_Http_HttpClientHandler_MaxConnectionsPerServer

    例如
    var client = new HttpClient(new HttpClientHandler { MaxConnectionsPerServer = 1000 });

    【讨论】:

    • 这是我在将 using 语句替换为您提供的语句后收到的新错误消息:e.Message “发送请求时发生错误。” e.InnerException.Message "无法连接到远程服务器"
    • 嗯,这个异常听起来像是防火墙或网络问题。我看不出它与这个设置有什么关系。
    • 或者你可能因为对服务器的请求过多而面临阻塞。
    • 好的,感谢您的洞察力。我更改了代码,使我有 4 个独立的客户端,每个客户端将执行 250 个请求。我将这些请求中的每一个都添加到任务列表中并调用 Task.WhenAll。似乎工作。对以这种方式解决我的问题有异议吗?
    • 这确实是一个更好的方法。对一个客户端做很多事情可能会给服务器带来很多限制。
    猜你喜欢
    • 2020-08-01
    • 2019-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-08
    • 2020-12-07
    • 2011-03-13
    相关资源
    最近更新 更多