运行多个异步阅读器不会异步运行

时间:2019-03-22 14:15:15

标签: c# async-await ado.net

在下面的代码中,我试图异步运行三个查询。当他们启动时,它肯定是异步的,因为它说“启动同步1,启动同步2,启动同步3”,这是立即的。当我非异步运行它时,会得到“开始同步1,结束同步1,...,如您所愿。

但是似乎每个调用都依次运行ExecuteReaderAsync,等待每个调用完成,然后再开始下一个调用,并在我依次运行它们时花完全相同的时间,并在每次之间等待相同的时间。

我的Sql服务器在另一台服务器上是Enterprise 2017。

我很欣赏异步是关于非阻塞任务的,但是在每个任务同时启动之后,我期望这三个任务中的每个任务都会在大约同一时间完成。取而代之的是,当它们一起开始时,实际的命令似乎在同步地执行,一个接一个地执行,花费的时间相同。

有人可以从异步的角度解释下面的代码实际上是如何运行的,为什么它没有达到我的预期?

即使我更改了execute语句并将其包装在Task.Run()中以将其放入线程池中,我也会得到完全相同的响应。

谢谢。

using System;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Threading.Tasks;

namespace AsyncSample
{
    internal class Tester
    {
        internal void Run()
        {
            AsyncTests();
            Console.ReadKey();
        }

        private async void AsyncTests()
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            var overallStart = sw.ElapsedMilliseconds;

            Task<bool> async1 = RunASync1();
            Task<bool> async2 = RunASync2();
            Task<bool> async3 = RunASync3();

            await Task.WhenAll(async1, async2, async3);

            var overallEnd = sw.ElapsedMilliseconds - overallStart;
            Console.WriteLine($"Sync test took {Math.Round(overallEnd / 1000.0, 1)} seconds.");
        }

        private async Task<bool> RunASync1()
        {
            Console.WriteLine("   async1 start");
            await RunASyncQuery("SELECT TOP 10000 * from TABLE1");
            Console.WriteLine("   async1 end");
            return true;
        }
        private async Task<bool> RunASync2()
        {
            Console.WriteLine("   async2 start");
            await RunASyncQuery("SELECT TOP 10000 * from TABLE2");
            Console.WriteLine("   async2 end");
            return true;
        }
        private async Task<bool> RunASync3()
        {
            Console.WriteLine("   async3 start");
            await RunASyncQuery("SELECT TOP 10000 * from TABLE3");
            Console.WriteLine("   async3 end");
            return true;
        }

        private async Task<bool> RunASyncQuery(string sql)
        {
            string connectionString = "Server=MyServer;Database=MyDatabase;Integrated Security=SSPI;Asynchronous Processing=true";
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                SqlCommand command = new SqlCommand(sql, connection);
                await connection.OpenAsync();
                SqlDataReader reader = await command.ExecuteReaderAsync();
            }
            return true;
        }
    }
}

0 个答案:

没有答案