我正在尝试模拟许多并发用户 (>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) { }
}
请注意,我的网络服务没有返回任何响应,也许这是速度变慢的原因?我可以发送请求而不等待响应吗?
请您参考如下方法:
为什么要用多线程来做这个?线程需要缓慢的 sleep /唤醒上下文切换。您可以使用计时器/异步调用来完成这一切。
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 并运行它们。
简单。
