问题
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