gpt4 book ai didi

c# - 如何发出并行 HTTP 请求

转载 作者:行者123 更新时间:2023-12-04 06:30:01 25 4
gpt4 key购买 nike

我有一个控制台应用程序,它向网页发出单个请求并返回其服务器状态,例如。 200、404等。

我想应用以下更改:

用户输入列表:

  • 请求网址
  • 使用多少并行连接(并发用户)
  • 提交尽可能多的请求需要多长时间(秒)

  • 输出列表:
  • 显示总获取次数
  • 显示每秒获取次数
  • 显示平均响应时间(毫秒)

  • 我想最好的方法是并行运行多个 http 提取并在单个进程中运行,这样它就不会使客户端机器陷入困境。

    我真的很喜欢 C#,但我还是个新手。我已经研究过关于此的其他文章,但我并不完全理解它们,因此将不胜感激任何帮助。

    我的代码:
    static void Main(string[] args)
    {
    try
    {
    HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("http://10.10.1.6/64k.html");
    webRequest.AllowAutoRedirect = false;
    HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse();
    //Returns "MovedPermanently", not 301 which is what I want.

    int i_goodResponse = (int)response.StatusCode;
    string s_goodResponse = response.StatusCode.ToString();
    Console.WriteLine("Normal Response: " + i_goodResponse + " " + s_goodResponse);
    Console.ReadLine();
    }
    catch (WebException we)
    {
    int i_badResponse = (int)((HttpWebResponse)we.Response).StatusCode;
    string s_badResponse = ((HttpWebResponse)we.Response).StatusCode.ToString();
    Console.WriteLine("Error Response: " + i_badResponse + " " + s_badResponse);
    Console.ReadLine();
    }
    }

    我发现的一些可能的代码:
    void StartWebRequest()
    {
    HttpWebRequest webRequest = ...;
    webRequest.BeginGetResponse(new AsyncCallback(FinishWebRequest), webRequest);
    }

    void FinishWebRequest(IAsyncResult result)
    {
    HttpWebResponse response = (result.AsyncState as HttpWebRequest).EndGetResponse(result) as HttpWebResponse;
    }

    最佳答案

    这实际上是利用 Task Parallel Library 的好地方在 .NET 4.0 中。我已将您的代码包装在 Parallel.For 中将并行执行多组请求的块,整理每个并行分支的总时间,然后计算整体结果。

    int n = 16;
    int reqs = 10;

    var totalTimes = new long[n];

    Parallel.For(0, n, i =>
    {
    for (int req = 0; req < reqs; req++)
    {
    Stopwatch w = new Stopwatch();
    try
    {
    w.Start();

    HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("http://localhost:42838/Default.aspx");
    webRequest.AllowAutoRedirect = false;
    HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse();

    w.Stop();
    totalTimes[i] += w.ElapsedMilliseconds;


    //Returns "MovedPermanently", not 301 which is what I want.
    int i_goodResponse = (int)response.StatusCode;
    string s_goodResponse = response.StatusCode.ToString();
    Console.WriteLine("Normal Response: " + i_goodResponse + " " + s_goodResponse);
    }
    catch (WebException we)
    {
    w.Stop();
    totalTimes[i] += w.ElapsedMilliseconds;

    int i_badResponse = (int)((HttpWebResponse)we.Response).StatusCode;
    string s_badResponse = ((HttpWebResponse)we.Response).StatusCode.ToString();
    Console.WriteLine("Error Response: " + i_badResponse + " " + s_badResponse);
    }
    }
    });

    var grandTotalTime = totalTimes.Sum();
    var reqsPerSec = (double)(n * reqs * 1000) / (double)grandTotalTime;

    Console.WriteLine("Requests per second: {0}", reqsPerSec);

    TPL 在这里非常有用,因为它抽象了在您的进程中创建多个执行线程以及在这些线程上运行每个并行分支的细节。

    请注意,在这里您仍然必须小心 - 我们无法共享在线程之间的任务期间更新的状态,因此 totalTimes 的数组它整理每个并行分支的总数,并在并行执行完成后才在最后汇总。如果我们不这样做,我们就会面临竞争条件的可能性——两个单独的线程试图同时更新总计数,这可能会破坏结果。

    我希望这是有道理的并且对您有用(我在这里只计算每秒请求数,其他统计数据应该相对容易添加)。如果您需要进一步说明,请添加评论。

    关于c# - 如何发出并行 HTTP 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5523854/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com