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.
asyncisn't concurrent, it'll run synchronously until something gives control back after registering with something like an IO completion port.DbConnection.