简体   繁体   中英

await/async Microsoft Practices Enterprise Library Data

I have an older application that I wrote where I used Microsoft.Practices.EnterpriseLibrary.Data to get data from the DB. I have recently upgraded to .NET 4.5 and wanted to advantage of await/async .

I do not see any methods ending in "Async" as per the naming standard, even in the most recent version of the package. Is it possible to use await/async with this ADO .NET library without manually making it asynchronous?

I'm using an older version of the EL that offers Begin* / End* methods, but not async versions. Some simple extension methods simplify life:

public static async Task<IDataReader> ExecuteReaderAsync(this SqlDatabase database, DbCommand command)
{
    return await Task<IDataReader>.Factory.FromAsync(database.BeginExecuteReader, database.EndExecuteReader, command, null);
}

public static async Task<object> ExecuteScalarAsync(this SqlDatabase database, DbCommand command)
{
    return await Task<object>.Factory.FromAsync(database.BeginExecuteScalar, database.EndExecuteScalar, command, null);
}

public static async Task<XmlReader> ExecuteXmlReaderAsync(this SqlDatabase database, DbCommand command)
{
    return await Task<XmlReader>.Factory.FromAsync(database.BeginExecuteXmlReader, database.EndExecuteXmlReader, command, null);
}

public static async Task<int> ExecuteNonQueryAsync(this SqlDatabase database, DbCommand command)
{
    return await Task<int>.Factory.FromAsync(database.BeginExecuteNonQuery, database.EndExecuteNonQuery, command, null);
}

I actually was able to find the Async methods. I was just looking in the wrong spots. Here's two common ways of accessing the DB asynchronously:

var db = DatabaseFactory.CreateDatabase(GlobalConstants.DBConnection);
using (var cmd = db.GetStoredProcCommand("SprocName", parameterA))
{
    await cmd.ExecuteNonQueryAsync();
}

and when you want to get data:

var db = DatabaseFactory.CreateDatabase(GlobalConstants.DBConnection);
using (var cmd = db.GetStoredProcCommand("SprocName", parameterA, parameterB, parameterC))
{
    using (var dr = await cmd.ExecuteReaderAsync())
    {
        while (await dr.ReadAsync())
        {
            return dr.GetInt32(0);
        }
    }
}

You can use GetFieldValueAsync<T> instead of GetInt32 if you are using CommandBehavior.SequentialAccess with large amounts of data. But, for most cases, you probably do not need to do this.

You'll probably find that it has methods like BeginXXX and EndXXXX , you can use those in conjunction with Task.Factory.FromAsync . More information here .

Here is an example of using it to read a file using Task.Factory.FromAsync in conjunction with filestream.BeginRead and filestream.EndRead

private async Task<string> ReadFileAsync()
{
  var fileStream = File.OpenRead("..\\..\\..\\test.txt"); 
  var buffer = new byte[1024];

  await Task<int>.Factory.FromAsync(fileStream.BeginRead, fileStream.EndRead, buffer, 0, buffer.Length, null);

  return System.Text.Encoding.ASCII.GetString(buffer);
}

This package was written initially in .NET 4.0. If you look at their source, they don't use async/await anywhere. http://topaz.codeplex.com/SourceControl/latest#source/Source/TransientFaultHandling/AsyncExecution.cs

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM