C# SQL connection OpenAsync is not asynchronous

Viewed 2545

I'm trying to open a connection to an SQL server asynchronously, so as not to tie up the UI thread. But I've found that the call to connection.OpenAsync() does not return until the connection has been opened, exactly as with connection.Open().

This code reproduces the issue:

public static void Main(string[] args)
{
    System.Data.SqlClient.SqlConnectionStringBuilder builder = new System.Data.SqlClient.SqlConnectionStringBuilder();
    builder.UserID = "sa";
    builder.Password = "1234";
    builder.DataSource = "192.168.1.254\\SQLEXPRESS";
    builder.InitialCatalog = "MyDatabase";
    builder.PersistSecurityInfo = true;

    DbConnection connection = new System.Data.SqlClient.SqlConnection(builder.ConnectionString);

    Console.WriteLine("about to connect");

    Task connection_task = connection.OpenAsync();

    Console.WriteLine("started");

    while (!connection_task.IsCompleted && !connection_task.IsFaulted && !connection_task.IsCanceled)
    {
        Console.WriteLine("busy");
    }

    Console.WriteLine("done");
}

In this case, 192.168.1.254 is non-existent. The message about to connect appears immediately, but then while waiting for the connection to time out nothing happens, then after the connection times out the messages started and done appear at the same time. I would expect that the message started would appear immediately after the message about to connect, then the message done would appear later once the connection has timed out.

I'm guessing that I'm doing something wrong with the returned Task, but the Microsoft page on Task-based Asynchronous Pattern certainly implies that I should simply be able to call the OpenAsync() method and the returned Task will be running asynchronously, instead of the operation taking place synchronously and tying up the calling thread until the Task completes.

2 Answers

It turns out that this is a bug in the Mono runtime and that the code works fine on Microsoft .NET. A similar bug also seems to be present with the MySQL .NET library (MySql.Data), which runs the task synchronously regardless of whether the Mono or the Microsoft .NET runtime is used.

EDIT: I've found a bug report for the issue with MySQL.

Try add Asynchronous Processing=True or Async=True property to your connection string,

and add await to function call, like this : await connection.OpenAsync();

I hope this help you.

Related