8

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?

PeteGO
  • 5,597
  • 3
  • 39
  • 70
ScubaSteve
  • 7,724
  • 8
  • 52
  • 65

4 Answers4

10

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);
}
Eric Patrick
  • 2,097
  • 2
  • 20
  • 31
  • #beautiful I updated all my layers (async/await) and found some Enterprise.Library.Data calls..and found this nugget. Thanks! – granadaCoder Apr 05 '18 at 15:48
  • Is there anyway to wire it to honor a CancellationToken? #askingForAFriend (especially ExecuteReaderAsync) – granadaCoder Apr 05 '18 at 15:50
  • @granadaCoder, I don't think there's an elegant methods to do so; see https://stackoverflow.com/questions/24980427/task-factory-fromasync-with-cancellationtokensource – Eric Patrick Apr 05 '18 at 20:10
  • That answer (accepted one from Stefan Z Camilleri) makes sense. Thanks for followup. – granadaCoder Apr 05 '18 at 20:32
6

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.

spottedmahn
  • 14,823
  • 13
  • 108
  • 178
ScubaSteve
  • 7,724
  • 8
  • 52
  • 65
  • What about opening the connection ? – Royi Namir Jun 24 '15 at 12:13
  • 2
    I actually don't see these methods now..I got the latest enterprise library data through Nuget and still not able to find these methods..Can you let me know the version of ent lib? – Bala Oct 27 '15 at 06:13
  • 2
    ExecuteReaderAsync is not from enterprise library - https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executereaderasync(v=vs.110).aspx – StingyJack Nov 22 '16 at 19:16
  • This is why I hate the use of "var" of online samples. You cannot see what they are. While this is a good answer for SqlClient.........the original question was about "Microsoft.Practices.EnterpriseLibrary.Data" Please post "using" statements in your sample so this is clearer to the reader. Thanks. – granadaCoder Apr 05 '18 at 15:53
-1

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);
}
NeddySpaghetti
  • 13,187
  • 5
  • 32
  • 61
-4

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

Kakira
  • 846
  • 1
  • 8
  • 14