without understanding run method await async c# .net oracle async-await odp.net-managed

understanding - use async await c#



¿Puede Oracle Managed Driver usar async/wait correctamente? (2)

Intentaba hacer una consulta de Oracle con la función async / wait .NET. El conjunto de resultados es bastante grande y tarda de 5 a 10 segundos en volver. El Window_Loaded está colgando el hilo de la IU, esencialmente quería usar async / wait para hacer la consulta en segundo plano y luego actualizar una vista de datos con el resultado.

Entonces, ¿es esto un problema del controlador de Oracle o un error de código? Por ejemplo, ¿se está haciendo algo de forma sincrónica en lugar de asincrónicamente? Estoy usando el último Oracle.ManagedDataAccess que podría obtener del sitio web de Oracle.

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(); }

Intenté esto, y todavía está bloqueando la interfaz de usuario:

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(); }

Así que al final, cambié el método a algo así para que no sea un punto muerto. Parece que tuve la idea correcta, solo que la biblioteca administrada por Oracle implementó los métodos Async de forma síncrona (solo para cumplir con la interfaz).

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(); }


(Dejo esto como una respuesta, ya que parece ser la "solución" para conseguir que el controlador administrado por Oracle soporte asincrónicamente).

Encontré un hilo viejo (de 2010) en el sitio de Oracle donde los PM de Oracle dicen que no lo admiten. Puede votar (debe tener una cuenta de Oracle) para tener esa característica incluida. Después de 5 años, lamentablemente solo obtuvo 60 votos.


No. El controlador administrado no es compatible con async / await .

Puede llamar a esos métodos, ya que deben implementarse para cumplir con la definición de interfaz, pero el código es realmente sincrónico. Puede usar Task.Run si lo desea, pero no puede tener dos llamadas al mismo tiempo (Oracle las amenazará sincrónicamente).