I understand that .NET 4.5 comes with a bunch of features to make asynchronous database operations easier to implement. MSDN says that if the connection string is not set to
I was into the same problem today and I made a Console Application to test whether it's working or not. Seems to me it's not working for my MySQL connector 6.9.4.
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace MySQLTest
{
class Program
{
static void Main(string[] args)
{
Service service = new Service();
var task1 = service.GetCountries("1");
var task2 = service.GetCountries("2");
var task3 = service.GetCountries("3");
Console.WriteLine("bö");
Console.ReadLine();
}
}
public class Service
{
public async Task<List<country>> GetCountries(string param)
{
Console.WriteLine(String.Format("{0} started.", param));
using (worldEntities context = new worldEntities())
{
Console.WriteLine(String.Format("{0} awaiting.", param));
List<country> countries = await context.country.ToListAsync();
Console.WriteLine(String.Format("{0} done.", param));
return new List<country>();
}
}
}
}
This one outputs,
And When I change List countries = await context.country.ToListAsync();
to await Task.Delay(5000);
it outpus :
after 5 seconds.
So I say it's not supported yet.
As Panagiotis Kanavos mentioned DbDataReader provides ReadAsync method signatures, however not all drivers support this. Some, like the MySql 6.9.5 driver, implement them synchronously.
To answer your more general question, if a (No)SQL driver does NOT inherently support *Async methods that are awaitable, but it does have "APM" IAsyncResult based methods (e.g. BeginRead.. EndRead...), then you can wrap those up using Task.Factory.FromAsync. Here is an example for MySql:-
public static class MySqlCommandExtension
{
public static Task<MySqlDataReader> MyExecuteReaderAsync(this MySqlCommand source, CommandBehavior behavior = CommandBehavior.Default)
{
return Task<MySqlDataReader>.Factory.FromAsync(source.BeginExecuteReader(behavior), source.EndExecuteReader);
}
}
This pattern is descibed in more detail on MSDN.
The asynchronous methods for all drivers are defined in DbDataReader, eg DbDataReader.ReadAsync. It is up to the specific drivers to override these methods with specific implementations to take advantage of the asynchronous characteristics of each database and use eg. a naturally asynchronous operation instead of a synchronous operation wrapped in a thread.
That said, MySQL Connector/Net 6.8 adds support for asynchronous operations in Entity Framework 6 but the MySqlDataReader class does NOT provide a ReadAsync
method. This is because Connector uses an old architecture (pre-2.0), implementing the IDataReader interface instead of deriving from the generic DbDataReader class introduced in .NET 2.0.