Заполнить GridViews Entity Framework асинхронно - PullRequest
0 голосов
/ 19 июня 2019

У меня есть форма, содержащая 4 вида сетки. Я хотел бы заполнить эти виды сетки объектами, которые я запрашиваю, благодаря Entity Framework. Проблема в том, что пользовательский интерфейс застревает во время загрузки. Таким образом, я попытался сделать запрос асинхронным, но он не работает. Я пытался сделать это несколькими способами, но мое текущее решение выглядит так

        private async void SwiftCheck_Load(object sender, EventArgs e)
        {
            radGridViewLast7Days.DataSource = await MonitoringToolCore.SwiftQueries.ReturnLast7DaysAsync();
            radGridViewAmount.DataSource = await MonitoringToolCore.SwiftQueries.CompareAmountsAsync();
            radGridViewAmountBySwift.DataSource = await MonitoringToolCore.SwiftQueries.CompareAmountsByTypeAsync();
            radGridViewAmountBySender.DataSource = await MonitoringToolCore.SwiftQueries.CompareAmountsBySenderAsync();

            //Code to adapt the gridviews layout after data has been bound
            this.radGridViewAmountBySender.BestFitColumns();

        }

Я связываю данные в событии загрузки, потому что, насколько я понимаю, я не могу использовать await в конструкторе. Затем я использую await для каждой задачи, потому что Entity Framework не является потокобезопасным. Так что, если я правильно понял, я не могу запустить каждую задачу одновременно, а потом ждать их всех?

Это один из кодов, который возвращает список объектов

        public static async Task<List<MsMessage>> ReturnLast7DaysAsync()
        {
            DateTime currentDate = DateTime.UtcNow.Date.AddDays(-7);

            using (var db = new SveulumeContext())
            {

                var query = db.MsMessages
                    .Where(u => u.Created >= currentDate);

                return await query.ToListAsync();               

            }
        }

Код работает и правильно связывает gridViews, но пользовательский интерфейс все еще блокируется в течение всего процесса. Что я делаю не так?

1 Ответ

1 голос
/ 19 июня 2019

Согласно этому ответу , Oracle не поддерживает асинхронные запросы в своей библиотеке .NET. Таким образом, способ выполнения асинхронного LINQ является правильным; просто Oracle этого не поддерживает. Вот почему вы видите, что запросы выполняются синхронно, а не асинхронно.

Чтобы получить код из потока пользовательского интерфейса, вы можете использовать Task.Run. Я рекомендую также добавить комментарий к коду, так как он выглядит неправильно:

// Task.Run is necessary because Oracle does not support async: https://stackoverflow.com/questions/29016698/can-the-oracle-managed-driver-use-async-wait-properly/29034291#29034291
radGridViewLast7Days.DataSource = await Task.Run(() => MonitoringToolCore.SwiftQueries.ReturnLast7DaysAsync());

Кстати, EF поддерживает несколько одновременных запросов , если каждый из них использует свой собственный контекст БД. Поскольку ваши методы используют собственный контекст БД, вы можете загрузить все эти запросы одновременно:

private async void SwiftCheck_Load(object sender, EventArgs e)
{
  // Task.Run is necessary because Oracle does not support async: https://stackoverflow.com/questions/29016698/can-the-oracle-managed-driver-use-async-

  var last7DaysTask = Task.Run(() => MonitoringToolCore.SwiftQueries.ReturnLast7DaysAsync());
  var compareAmountsTask = Task.Run(() => MonitoringToolCore.SwiftQueries.CompareAmountsAsync());
  var compareAmountsByTypeTask = Task.Run(() => MonitoringToolCore.SwiftQueries.CompareAmountsByTypeAsync());
  var compareAmountsBySenderTask = Task.Run(() => MonitoringToolCore.SwiftQueries.CompareAmountsBySenderAsync());
  await Task.WhenAll(last7DaysTask, compareAmountsTask, compareAmountsByTypeTask, compareAmountsBySenderTask);
  radGridViewLast7Days.DataSource = await last7DaysTask;
  radGridViewAmount.DataSource = await compareAmountsTask;
  radGridViewAmountBySwift.DataSource = await compareAmountsByTypeTask;
  radGridViewAmountBySender.DataSource = await compareAmountsBySenderTask;

  //Code to adapt the gridviews layout after data has been bound
  this.radGridViewAmountBySender.BestFitColumns();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...