简体   繁体   English

针对C#异步的秒表:我被秒表所迷惑了,还是有我不知道的东西?

[英]Stopwatch against C# Async: Am I fooled by the stopwatch or there's something there I don't know?

Basically, I want to stopwatch against an async API call to Google BigQuery. 基本上,我想秒表针对对Google BigQuery的异步API调用。 I meant to design the test run in two modes: (1)single thread mode -- call the API, wait for it to finish its task and then fire the next call. 我打算以两种模式设计测试运行:(1)单线程模式-调用API,等待其完成任务,然后触发下一个调用。 (2) multiple thread mode -- start multiple calls through Task.Run, then wait for them all. (2)多线程模式-通过Task.Run启动多个调用,然后等待所有调用。 The test result is very confused, according to the stopwatch. 根据秒表,测试结果非常混乱。 In the first mode, each API call finishes its task within around 300ms, but in the second mode, except for the first few calls, each API call takes over 10 seconds. 在第一种模式下,每个API调用均在300毫秒内完成其任务,但是在第二种模式下,除了前几个调用之外,每个API调用都需要10秒钟以上。 That's a huge difference! 那是巨大的差异! (Windows 8.1 Pro, 8GB RAM, 2-cores CPU) (Windows 8.1 Pro,8GB RAM,2核CPU)

It could be something on the Google BigQuery side, but besides that possibility, I want to ensure that I'm using stopwatch correctly, or I mean I'm measuring what I meant to measure. 可能是Google BigQuery方面的问题,但除了这种可能性之外,我还想确保自己正确使用了秒表,或者我正在衡量自己要衡量的内容。 Am I? 是吗

Here's the code: 这是代码:

 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();
    }

Stopwatch in the InsertAsync: 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);

Solve Thanks very much to the following answer. 解决非常感谢以下回答。 I ended up add several lines in my app.config, and it solves this problem. 我最终在我的app.config中添加了几行,它解决了这个问题。

<system.net>
<connectionManagement>
    <add address="*" maxconnection="2000" />
</connectionManagement>
</system.net>

You are most likely running into the concurrent connection limit in .Net as illustrated in this question: Max number of concurrent HttpWebRequests . 如以下问题所示,您最有可能遇到.Net中的并发连接限制: 并发HttpWebRequests的最大数量

The maximum number of concurrent requests to a single host is limited. 限制到单个主机的最大并发请求数。 So what is happening is the first couple of requests go through immediately, but once the limit is hit the latter requests start blocking and waiting until the first requests finish. 因此,发生的事情是前几个请求立即通过,但是一旦达到限制,后一个请求将开始阻塞并等待第一个请求完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM