【问题标题】:Sending many parrallel WebRequests发送许多并行 Web 请求
【发布时间】:2017-06-23 07:35:37
【问题描述】:

我正在尝试模拟许多并发用户 (>2000) 来测试 Web 服务。每个用户在特定的预定义时间执行操作,例如:

  • 用户A:09:10:02、09:10:03、09:10:08
  • 用户 B:09:10:03、09:10:05、09:10:07
  • 用户 C:09:10:03、09:10:09、09:10:15、09:10:20

我现在想在每个时间实时发送网络请求。我最多可以容忍约 2 秒的延迟。我已经在尝试但没有成功:

a) 将所有时间聚合到一个列表中,按时间排序,然后对其进行迭代:

foreach (DateTime sendTime in times) {
    while (DateTime.now < sendTime)
        Thread.Sleep(1);
    SendRequest();
}

b) 为每个用户创建一个线程,每个线程检查与上述相同的条件,但睡眠时间更长

这两种方法都可以工作,但是请求应该发送的时间和实际发送的时间之间的延迟太高了。有什么方法可以更高精度地发送请求吗?

编辑:建议的方法非常有效。但是,对于许多请求,延迟仍然非常高。显然,原因是我的 SendRequest() 方法:

private static async Task SendRequest()
{
    // Log time difference
    string url = "http://www.request.url/newaction";
    WebRequest webRequest = WebRequest.Create(url);
    try
    {
        WebResponse webResponse = await webRequest.GetResponseAsync();
    }
    catch (Exception e) { }
 }

请注意,我的 Web 服务没有返回任何响应,这可能是速度变慢的原因?我可以在不等待响应的情况下发送请求吗?

【问题讨论】:

  • 还有你的问题?
  • 我添加了一个更具体的问题

标签: c# .net multithreading webrequest


【解决方案1】:

你为什么要用多线程来做这个?线程需要缓慢的睡眠/唤醒上下文切换。你可以通过定时器/异步调用来完成这一切。

List<DateTime> scheduledTimes = ...;
List<Task> requests = scheduledTimes
                         .Select(t => t - DateTime.Now)
                         .Select(async delay => 
                         {
                             await Task.Delay(delay);
                             SendRequest();
                         })
                         .ToList();

await Task.WhenAll(requests);

以上代码将在一个线程中将所有请求调度到SynchronizationContext 并运行它们。

简单。

【讨论】:

  • 谢谢,这真的很好用。但是,由于我的 SendRequest() 方法,许多请求的延迟仍然很高。我编辑了我的帖子以获取更多信息。
  • @aseipel 我认为实际上原因是因为您达到了 connectionManager 限制。您也有可能达到了 http 服务器的限制(非服务器 Windows 上的 IIS 也故意受到连接限制的限制)。
  • 如何检查是否是这种情况?我已经在我的 App.config 中增加了 maxconnection 属性、我的服务的 IIS 连接限制和应用程序池 queueLength。
  • @aseipel 您在 IIS 上运行的 Windows 版本是什么? jpelectron.com/sample/WWW%20and%20HTML/…您可以通过卸载 Windows 并安装服务器版本的 Windows 来更改这些限制。
  • 我在 Windows 7 上同时运行服务和我的测试应用程序。但是,我现在已经将这两个程序部署在两个使用 Windows Server 2016 的不同服务器上。在请求中,我发送了两个时间戳: a) 应该发送请求的时间(在 scheduleTimes 列表中确定)以及实际发送请求的时间。事实证明,发送请求的应用程序太慢了,因为实际发送/接收之间的差异接近于零,而应该发送/接收之间的差异一直在上升
【解决方案2】:

我建议使用计时器对象来触发请求:

// In Form_Load or another init method
Timer tRequest = new Timer();
tRequest.Interval = 500;
tRequest.Tick += TRequest_Tick;

private void TRequest_Tick(object sender, EventArgs e)
{
     var sendTimes = times.Where(t => t.AddMilliseconds(-500) < DateTime.Now && t.AddMilliseconds(500) > DateTime.Now);

     foreach(DateTime sendTime in sendTimes)
     {
         SendRequest();
     }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-23
    • 1970-01-01
    • 1970-01-01
    • 2013-07-31
    • 2020-04-23
    • 1970-01-01
    相关资源
    最近更新 更多