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(); }
C# Language Async-Await Async/await will only improve performance if it allows the machine to do additional work.
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.
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.
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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With