Async odbc seems to be synchronous

不羁岁月 提交于 2021-02-07 18:43:24

问题


I'm trying to do async database queries, but when I test my code it appears to be synchronous. I've isolated the issue to my Query function. Can't figure out what I'm doing wrong, I'm pretty new to the aync/await functionality so it's possible that I've done something stupid :)

This is the failing code: (i'm using a local install of 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();
        }
    }

When I run this code I get this output:

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!

Why doesn't the second and third task start directly? And why does it take 16 seconds?

I've tried to replace the call to my Query function with await Task.Delay(seconds * 1000) and when i do that the code executes asynchronously like this:

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:


The problem was that I assumed that OdbcConnection.OpenAsync() and OdbcCommand.ExecuteReaderAsync() is infact async methods, which they aren't.

I had read on msdn how to use SqlConnection and SqlCommand async and thougt I could apply that to OdbcConnection/OdbcCommand which turned out to be false.

I've got it working by using Npgsql:s NpgsqlConnection, NpgsqlCommand and NpgsqlParameter classes instead of .NETs Odbc-classes.



来源:https://stackoverflow.com/questions/47011111/async-odbc-seems-to-be-synchronous

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!