Я пытался сделать запрос Oracle с помощью функции async / wait .NET. Набор результатов довольно большой и возврат занимает около 5-10 секунд. Window_Loaded подвешивает поток пользовательского интерфейса, по сути, я хотел использовать async / wait, чтобы выполнить запрос в фоновом режиме, а затем обновить представление данных с результатом.
Так это проблема с драйвером 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();
}
Я пробовал это, но пользовательский интерфейс все еще блокируется:
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();
}
2 ответа
Нет. Управляемый драйвер не поддерживает async
/ await
.
Вы можете вызывать эти методы, поскольку они должны быть реализованы в соответствии с определением интерфейса, но на самом деле код является синхронным. Вы можете использовать Task.Run
, если хотите, но вы не можете иметь два вызова одновременно (Oracle будет угрожать им синхронно).
(Я оставляю это как ответ, поскольку это, по-видимому, «решение» для того, чтобы управляемый драйвер Oracle правильно поддерживал асинхронность.)
Я нашел старую ветку (от 2010 г.) на сайте Oracle, где сотрудники Oracle PM говорят, что не поддерживают Это. Вы можете проголосовать (должна иметь учетную запись Oracle), чтобы включить эту функцию. К сожалению, через 5 лет он получил только 60 голосов.
Похожие вопросы
Связанные вопросы
Новые вопросы
c#
C # (произносится как «резкий») - это высокоуровневый, статически типизированный язык программирования с несколькими парадигмами, разработанный Microsoft. Код C # обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, включая, среди прочего, .NET Framework, .NET Core и Xamarin. Используйте этот тег для вопросов о коде, написанном на C # или в формальной спецификации C #.