针对 C# 异步的秒表:我是被秒表愚弄了还是有什么我不知道的?
Stopwatch against C# Async: Am I fooled by the stopwatch or there's something there I don't know?
基本上,我想针对对 Google BigQuery 的异步 API 调用进行秒表。我打算在两种模式下设计测试 运行:(1) 单线程模式——调用 API,等待它完成任务,然后触发下一个调用。 (2) 多线程模式——通过Task.Run启动多个调用,然后全部等待。根据秒表,测试结果非常混乱。在第一种模式下,每个 API 调用在大约 300 毫秒内完成其任务,但在第二种模式下,除了前几个调用外,每个 API 调用需要 10 多秒。这是一个巨大的差异! (Windows 8.1 Pro,8GB RAM,2 核 CPU)
可能是 Google BigQuery 方面的问题,但除此之外,我想确保我正确使用了秒表,或者我的意思是我正在测量我想要测量的东西。我是吗?
代码如下:
static void Main(string[] args)
{
// SingleThreadMode();
MultiThreadMode();
}
private static void SingleThreadMode()
{
var batch = ReadOneBatchInArrays();
for (int i = 0; i < 100; i++)
{
try
{
Task.Run(async () => { await InsertAsync("T20150624", batch, InsertId); }).Wait(-1);
}
catch (AggregateException e)
{
foreach (var exception in e.InnerExceptions)
{
Console.WriteLine(exception);
}
}
}
Console.WriteLine("End");
Console.ReadLine();
}
private static void MultiThreadMode()
{
var batch = ReadOneBatchInArrays();
IList<Task> tasks = new List<Task>();
for (int i = 0; i < 100; i++)
{
try
{
tasks.Add(Task.Run(async () => { await InsertAsync("T20150624", batch, InsertId); }));
}
catch (AggregateException e)
{
foreach (var exception in e.InnerExceptions)
{
Console.WriteLine(exception);
}
}
}
Task.WaitAll(tasks.ToArray(),-1);
Console.WriteLine("End");
Console.ReadLine();
}
InsertAsync 中的秒表:
Stopwatch stopwatch = Stopwatch.StartNew();
TableDataInsertAllResponse response = await BqService.Tabledata.InsertAll(request, ProjectId, DatasetId, tableId).ExecuteAsync();
stopwatch.Stop();
Logger.Trace("BigQuery.InsertAll#Back|row count|milliseconds~{0}~{1}", rowList.Count, stopwatch.ElapsedMilliseconds);
求解
非常感谢以下回答。我最终在 app.config 中添加了几行,它解决了这个问题。
<system.net>
<connectionManagement>
<add address="*" maxconnection="2000" />
</connectionManagement>
</system.net>
您很可能 运行 进入 .Net 中的并发连接限制,如以下问题所示:。
单个主机的最大并发请求数有限制。所以发生的是前几个请求立即通过,但一旦达到限制,后一个请求开始阻塞并等待第一个请求完成。
基本上,我想针对对 Google BigQuery 的异步 API 调用进行秒表。我打算在两种模式下设计测试 运行:(1) 单线程模式——调用 API,等待它完成任务,然后触发下一个调用。 (2) 多线程模式——通过Task.Run启动多个调用,然后全部等待。根据秒表,测试结果非常混乱。在第一种模式下,每个 API 调用在大约 300 毫秒内完成其任务,但在第二种模式下,除了前几个调用外,每个 API 调用需要 10 多秒。这是一个巨大的差异! (Windows 8.1 Pro,8GB RAM,2 核 CPU)
可能是 Google BigQuery 方面的问题,但除此之外,我想确保我正确使用了秒表,或者我的意思是我正在测量我想要测量的东西。我是吗?
代码如下:
static void Main(string[] args)
{
// SingleThreadMode();
MultiThreadMode();
}
private static void SingleThreadMode()
{
var batch = ReadOneBatchInArrays();
for (int i = 0; i < 100; i++)
{
try
{
Task.Run(async () => { await InsertAsync("T20150624", batch, InsertId); }).Wait(-1);
}
catch (AggregateException e)
{
foreach (var exception in e.InnerExceptions)
{
Console.WriteLine(exception);
}
}
}
Console.WriteLine("End");
Console.ReadLine();
}
private static void MultiThreadMode()
{
var batch = ReadOneBatchInArrays();
IList<Task> tasks = new List<Task>();
for (int i = 0; i < 100; i++)
{
try
{
tasks.Add(Task.Run(async () => { await InsertAsync("T20150624", batch, InsertId); }));
}
catch (AggregateException e)
{
foreach (var exception in e.InnerExceptions)
{
Console.WriteLine(exception);
}
}
}
Task.WaitAll(tasks.ToArray(),-1);
Console.WriteLine("End");
Console.ReadLine();
}
InsertAsync 中的秒表:
Stopwatch stopwatch = Stopwatch.StartNew();
TableDataInsertAllResponse response = await BqService.Tabledata.InsertAll(request, ProjectId, DatasetId, tableId).ExecuteAsync();
stopwatch.Stop();
Logger.Trace("BigQuery.InsertAll#Back|row count|milliseconds~{0}~{1}", rowList.Count, stopwatch.ElapsedMilliseconds);
求解 非常感谢以下回答。我最终在 app.config 中添加了几行,它解决了这个问题。
<system.net>
<connectionManagement>
<add address="*" maxconnection="2000" />
</connectionManagement>
</system.net>
您很可能 运行 进入 .Net 中的并发连接限制,如以下问题所示:。
单个主机的最大并发请求数有限制。所以发生的是前几个请求立即通过,但一旦达到限制,后一个请求开始阻塞并等待第一个请求完成。