Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can the Oracle managed driver use async/await properly?

I was trying to make an Oracle query with the async/await .NET feature. The result set is pretty large and takes about 5-10 seconds to come back. The Window_Loaded is hanging the UI thread, essentially I wanted to use async/wait to do the query in the background and then update a dataview with the result.

So is this an Oracle driver issue or a code error? E.g. is something here being done synchronously instead of asynchronously? I'm using the latest Oracle.ManagedDataAccess I could get from Oracle's web-site.

async Task<DataTable> AccessOracleAsync() {     DataTable dt;     using(OracleConnection conn = new OracleConnection(ConfigurationManager         .ConnectionStrings["connStr"].ConnectionString))     using (OracleCommand cmd = new OracleCommand(@"SELECT * FROM myTbl", conn))     {         await conn.OpenAsync();         using (var reader = await cmd.ExecuteReaderAsync())         {             dt = new DataTable();             dt.Load(reader);                                 }     }     return dt; }  private async void Window_Loaded(object sender, RoutedEventArgs e) {     await AccessOracleAsync(); } 

I tried this, and it is still blocking the UI:

async Task<DataView> AccessOracleAsync() {     DataTable dt;     using (OracleConnection conn = new OracleConnection(ConfigurationManager         .ConnectionStrings["connStr"].ConnectionString))     using (OracleCommand cmd = new OracleCommand(@"SELECT * FROM myTbl", conn))     {         await conn.OpenAsync().ConfigureAwait(false);         using (DbDataReader reader = await cmd.ExecuteReaderAsync().ConfigureAwait(false))         {             dt = new DataTable();             await Task.Run(() => dt.Load(reader)).ConfigureAwait(false);         }     }     return dt.AsDataView(); }  private async void Window_Loaded(object sender, RoutedEventArgs e) {     Data1.ItemsSource = await AccessOracleAsync(); } 

So in the end, I changed the method to something like this to make it not block. It appears I had the right idea, just that the Oracle managed library implemented the Async methods synchronously (only to comply with the interface).

private async Task<DataView> AccessOracleAsync() {     DataTable dt = new DataTable();     using (OracleConnection conn = new OracleConnection(ConfigurationManager         .ConnectionStrings["connStr"].ConnectionString))     using (OracleCommand cmd = new OracleCommand(@"SELECT * myTbl", conn))     {         await Task.Run(() =>         {             conn.Open();             using (DbDataReader reader = cmd.ExecuteReader())             {                 dt.Load(reader);             }         }).ConfigureAwait(false);     }     return dt.AsDataView(); } 
like image 761
user17753 Avatar asked Mar 12 '15 17:03

user17753


People also ask

Does async await improve performance?

C# Language Async-Await Async/await will only improve performance if it allows the machine to do additional work.

Should you always await async methods?

If a method is declared async, make sure there is an await! If your code does not have an await in its body, the compiler will generate a warning but the state machine will be created nevertheless, adding unnecessary overhead for an operation that will actually never yield.

Is await async the same as sync?

Async/await helps you write synchronous-looking JavaScript code that works asynchronously. Await is in an async function to ensure that all promises that are returned in the function are synchronized. With async/await, there's no use of callbacks.

What is one benefit of using async await?

The biggest advantage of using async and await is, it is very simple and the asynchronous method looks very similar to a normal synchronous methods. It does not change programming structure like the old models (APM and EAP) and the resultant asynchronous method look similar to synchronous methods.


1 Answers

No. The managed driver does not support async / await.

You can call those methods, since they must be implemented to comply with the interface definition, but the code is actually synchronous. You can use Task.Run if you want to, but you can't have two calls at the same time (Oracle will threat them synchronous).

like image 91
Patrick Hofman Avatar answered Sep 22 '22 09:09

Patrick Hofman