4

So because the OracleCommand class extends the DbCommand class it implements the Async versions of it's Execute methods. However, I cannot find any reference to that OracleCommand class supporting these methods from Oracle (I am using 11g): http://docs.oracle.com/html/E10927_01/OracleCommandClass.htm

Do anyone know what this is doing under the hood to support these methods? They appear to be non-blocking and support cancellation in usage (I expected a NotImplementedException to be honest), but this feels unsupported to me because of the documentation so I want to make sure that there aren't any gotchas.

ChoptimusPrime
  • 433
  • 7
  • 15

1 Answers1

2

The Oracle client doesn't override the async versions of the methods. They use the default DbCommand implementnations which call the non-async versions of the methods.

For example, the implementation of ExecuteNonQueryAsync is:

// System.Data.Common.DbCommand
public virtual Task<int> ExecuteNonQueryAsync(CancellationToken cancellationToken)
{
    if (cancellationToken.IsCancellationRequested)
    {
        return ADP.CreatedTaskWithCancellation<int>();
    }
    CancellationTokenRegistration cancellationTokenRegistration = default(CancellationTokenRegistration);
    if (cancellationToken.CanBeCanceled)
    {
        cancellationTokenRegistration = cancellationToken.Register(new Action(this.CancelIgnoreFailure));
    }
    Task<int> result;
    try
    {
        result = Task.FromResult<int>(this.ExecuteNonQuery());
    }
    catch (Exception ex)
    {
        cancellationTokenRegistration.Dispose();
        result = ADP.CreatedTaskWithException<int>(ex);
    }
    return result;
}

As you can see, it simply calls ExecuteNonQuery under the hood (the no-parameter overload of ExecuteNonQueryAsync calls this version of the method).

Pete
  • 6,585
  • 5
  • 43
  • 69
  • Ah, I guess was hoping for something a little more clever like this:http://stackoverflow.com/questions/16614035/timeout-for-oracledatareader-read-method. Thanks. – ChoptimusPrime Oct 25 '13 at 20:58
  • Well, there's really no reason to do a separate implementation. This is, I feel, the more elegant way of implementing it as it requires the vendor to only implement the non-async method and they get the async ones for free. It also ensures consistency among vendors, at least in terms of how the async stuff is handled. – Pete Oct 25 '13 at 21:13
  • 1
    They don't get them for free since this isn't actually asynchronous (it blocks the calling thread). This leaves no way to abort long running operations. The implementation that I linked to is blocking as well maybe on another thread, but it can support cancellation tokens with some modifications by going around the Task and telling the DB to cancel the query when needed. That might require two blocked threads though, without a predetermined timeout. That could actually make this the better implementation. None of this is as good as some non-blocking implementation though. – ChoptimusPrime Oct 28 '13 at 20:02
  • See my comment to my question also, I was a bit too hasty in my determination of blocking/cancelable here. – ChoptimusPrime Oct 28 '13 at 20:04
  • @ChoptimusPrime Though this example is for MySQL, the basic patterns apply. Hopefully this will help you: http://www.devart.com/dotconnect/mysql/docs/Asynchronous.html – Pete Oct 28 '13 at 20:49
  • I am familiar with them, and that company actually has a third party Oracle tool as well. What isn't entirely clear from that documentation though is if that call is still blocking some thread. Selling my employer (and others I would image) on using a third party tool for this is non trivial though in any case. – ChoptimusPrime Oct 29 '13 at 15:26