Próbowałem utworzyć kwerendę Oracle z funkcją async/wait .NET. Zestaw wyników jest dość duży i potrzeba około 5-10 sekund, aby powrócić. Window_Loaded zawiesza wątek interfejsu użytkownika, w zasadzie chciałem użyć async/wait, aby wykonać zapytanie w tle, a następnie zaktualizować widok danych z wynikiem.Czy sterownik zarządzany przez Oracle może korzystać z asynchronizacji/czekać poprawnie?
Czy jest to również problem sterownika Oracle lub błąd kodu? Na przykład. czy coś tu robi się synchronicznie, zamiast asynchronicznie? Używam najnowszego Oracle.ManagedDataAccess
, które mogę uzyskać z witryny internetowej 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();
}
Próbowałem to i jest nadal deadlocking 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();
}
Więc w końcu, zmieniłem metodę do czegoś takiego by nie impasu . Wygląda na to, że miałem dobry pomysł, tylko że biblioteka zarządzana przez Oracle zaimplementowała metody Asynchroniczne synchronicznie (tylko po to, aby zachować zgodność z interfejsem).
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();
}
Co można spróbować to wziąć kod dt.Load (czytnik); do zadania takiego jak Task.Run (() => dt.Load (czytnik)); Dalej kod wygląda dobrze dla mnie. –
Do tej pory wysłałem do Oracle e-maila na temat asynchronicznego wsparcia i otrzymałem odpowiedź: "Nie mam żadnych nowych informacji, kiedy spodziewać się asynchronizacji dla ODP.NET, zarządzanego sterownika." – mason