Is Oracle OpenAsync etc... not a truly async method?

Viewed 391

I have an Oracle database that I am accessing through ODP.NET

This is my demo code

public static async Task<Field[][]> ReadAsync(string ExtractSql)
{
    var connStr = ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString;
    List<Field[]> ret = new List<Field[]>();
    using (OracleConnection conn = new OracleConnection(connStr))
    {
        await conn.OpenAsync();
    }
    return ret.ToArray();
}

This code does not behave as async, the UI is completely blocked for seconds. If I simply replace

await Task.Delay(10000); //conn.OpenAsync();

all works fine as expected. Can I conclude that this is a bug in ODP.NET, is there a github repo or where can I report it or am I missing something trivial in C# async?

Is there anyone else using .NET for Oracle and experiencing a similar issue for async methods?

Please note

Of course I've added the code inside to open the command and read the data and the issue persists, here I'm showing the minimal amount of code that is sufficient to detect the problem. E.g. I have a firewall that can block the connection and in that case it times out, therefore the only "open" command can be enough to make the app stuck, if the db part is not async.

1 Answers

Thank you to @madreflection for the comments. I'm really happy to delete my answer and accept an answer from him, as I kindly asked.

Anyway, now it is clear by looking at Visual Studio intellisense that those async methods are not there but they are symply inherited from the generic System.Data.Common.DbConnection.

I should have also understood it at the first method that is not returning a Task or a Task<bool>, i.e. from the following line

OracleDataReader DR = (OracleDataReader) await cmd.ExecuteReaderAsync();

where I was forced to add an unexpected cast (now I understand why).

I'm going to wrap the API in a Task.Run because I can't block my UI.

See below the screenshot with the mouse over the OpenAsync.

enter image description here

From the doc you can read

This is the asynchronous version of Open(). Providers should override with an appropriate implementation The default implementation invokes the synchronous Open() call and returns a completed task.

My person opinion is that the default implementation is doing the wrong/misleading thing, I would have rather preferred an exception "not implemented" thrown instead.

Related