我正在尝试使用异步/等待.NET功能进行Oracle查询.结果集相当大,大概需要5-10秒才能回来. Window_Loaded挂起了UI线程,本质上我想使用async / wait在后台执行查询,然后用结果更新dataview.
那么这是Oracle驱动程序问题还是代码错误?例如.这里的东西是同步进行的,而不是异步的吗?我使用最新的Oracle.ManagedDataAccess我可以从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(); }
我尝试过这个,但是它仍然是僵局的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(); }
所以最后,我把方法改成了这样的东西,使它不会死锁.看来我有正确的想法,只是Oracle Managed库同步地实现了Async方法(仅符合接口).
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(); }