代码之家  ›  专栏  ›  技术社区  ›  doktron

异步odbc似乎是同步的

  •  4
  • doktron  · 技术社区  · 8 年前

    我试图进行异步数据库查询,但当我测试代码时,它似乎是同步的。我已将问题隔离到查询函数。我不知道我做错了什么,我对aync/await功能相当陌生,所以我可能做了一些愚蠢的事情:)

    这是失败的代码:(我正在使用postgresql的本地安装)

        public static void Main()
        {
            Task.Run(async () => await MainAsync()).GetAwaiter().GetResult();
        }
    
        public static async Task MainAsync()
        {
            await TestDbSleep(5);
        }
    
        public static async Task TestDbSleep(int seconds)
        {
            Console.WriteLine("{0} Starting tasks!", DateTime.Now.ToString("HH:mm:ss"));
            var tasks = new[] { DbSleep(5, "first"), DbSleep(seconds, "second"), DbSleep(seconds, "third") };
            Console.WriteLine("All tasks started!");
            await Task.WhenAll(tasks);
            Console.WriteLine("{0} All tasks done!", DateTime.Now.ToString("HH:mm:ss"));
        }
    
        public static async Task<DbDataReader> DbSleep(int seconds, string name)
        {
            Console.WriteLine("Starting {0}!", name);
            var result = await Query("SELECT * FROM pg_sleep(?)", new OdbcParameter("seconds", seconds));
            Console.WriteLine("{0} done!", name);
            return result;
        }
    
        public static async Task<DbDataReader> Query(string sql, params OdbcParameter[] parameters)
        {   
            using (var dbConn = new OdbcConnection(ConfigurationManager.ConnectionStrings["MainConnectionString"].ConnectionString))
            {
                await dbConn.OpenAsync();
                var command = new OdbcCommand(sql, dbConn);
                if (parameters != null)
                {
                    foreach (var parameter in parameters)
                    {
                        command.Parameters.Add(parameter);
                    }
                }
                return await command.ExecuteReaderAsync();
            }
        }
    

    当我运行此代码时,我得到以下输出:

    09:29:20 Starting tasks!
    Starting first!
    first done!
    Starting second!
    second done!
    Starting third!
    third done!
    All tasks started!
    09:29:36 All tasks done!
    

    我试图用等待任务替换对查询函数的调用。延迟(秒*1000),当我这样做时,代码异步执行如下:

    09:29:15 Starting tasks!
    Starting first!
    Starting second!
    Starting third!
    All tasks started!
    third done!
    second done!
    first done!
    09:29:20 All tasks done!
    
    1 回复  |  直到 8 年前
        1
  •  3
  •   doktron    8 年前

    问题是我假设ODBC连接。OpenAsync()和OdbcCommand。ExecuteReaderAsync()实际上是异步方法,但事实并非如此。

    我在msdn上读到了如何使用SqlConnection和SqlCommand async,我认为我可以将其应用于OdbcConnection/OdbcCommand,但结果是错误的。

    我通过使用Npgsql:s NpgsqlConnection、NpgsqlCommand和NpgsqlParameter类而不是。NETs Odbc类。