异步odbc似乎是同步的 [英] Async odbc seems to be synchronous

查看:65
本文介绍了异步odbc似乎是同步的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试进行异步数据库查询,但是当我测试我的代码时,它似乎是同步的.我已将问题隔离到查询功能中.无法弄清楚我在做什么错,我对aync/await功能还很陌生,所以可能我做了一些愚蠢的事情:)

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 :)

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

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!

为什么第二个和第三个任务不直接启动?为什么要花16秒?

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

我试图用Task.Delay(seconds * 1000)替换对Query函数的调用,当我这样做时,代码将异步执行:

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!

推荐答案

问题是我假设OdbcConnection.OpenAsync()和OdbcCommand.ExecuteReaderAsync()是实际上不是它们的异步方法.

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

我已经在msdn上阅读了如何使用SqlConnection和SqlCommand async,并且可以将其应用于OdbcConnection/OdbcCommand,事实证明它是错误的.

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.

我已经使用Npgsql:s的NpgsqlConnection,NpgsqlCommand和NpgsqlParameter类而不是.NETs Odbc类来使它起作用.

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

这篇关于异步odbc似乎是同步的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆