Обновление DataTable при чтении результатов из другого потока - PullRequest
1 голос
/ 09 февраля 2020

Я создаю приложение wpf в c#. Я хочу иметь DataGrid, который обновляется с результатами по мере их извлечения из базы данных (т. Е. Они отображают в DataGrid по строке за раз, когда они извлекаются, очень похоже на функцию поиска в проводнике, где результаты всплывают один за другим). время, когда они найдены, вместо того, чтобы иметь пустую страницу результатов, а затем все они появляются сразу.

Это моя первая реальная попытка использования асин c методов и многопоточности, так что я конечно, есть проблемы, но именно поэтому я экспериментирую

Что у меня есть до сих пор:

  • asyn c методы для получения данных из базы данных. Я доказал, что это работает.
  • Обратите внимание, что я сейчас использую SQL для экспериментов - как только у меня это получится, я не буду использовать SQL напрямую, но хранимые процедуры и параметры
  • функции получения базы данных передается DataTable, чтобы позволить ей добавлять строку за раз, когда данные считываются:
        private static async Task ExecuteTextQueryAsync(string SQLText, OracleConnection conn, DataTable dt)
        {
            using (OracleCommand cmd = new OracleCommand(SQLText))
            {
                cmd.BindByName = true;
                cmd.CommandType = CommandType.Text;

                cmd.Connection = conn;

                using (System.Data.Common.DbDataReader reader = await cmd.ExecuteReaderAsync()) 
                {
                    if (reader.HasRows)
                    {
                        DataTable schemaTable = reader.GetSchemaTable();
                        foreach (DataRow row in schemaTable.Rows)
                        {
                            string colName = row.Field<string>("ColumnName");
                            Type t = row.Field<Type>("DataType");
                            dt.Columns.Add(colName, t);
                        }
                        while (await reader.ReadAsync())
                        {
                            var newRow = dt.Rows.Add();
                            foreach (DataColumn col in dt.Columns)
                            {
                                newRow[col.ColumnName] = reader[col.ColumnName];
                            }
                        }
                    }
                }
            }
        }

Теперь, когда я используя MVVM, я вызываю не вышеуказанный метод из кода, а из модели представления. Viewmodel:

  • Имеет свойство DataTable ResultDataGrid, которое связано с сеткой данных в представлении.
  • Я создал этот объект DataTable, а также добавил обработчик события для события TableNewRow, которое должен запускаться всякий раз, когда в таблицу добавлена ​​строка (что приводит к вызову NotifyPropertyChanged для указанного выше свойства
  • Затем я пытаюсь запустить вышеуказанный метод получения данных в другом потоке и надеюсь, что таблица обновится как добавлены новые строки:
using (OracleConnection newConnection = Helper.CreateConnectionAsync(ConnectionStr).Result)
            {
                try
                {
                    var task = Task.Run(async () => { await Helper.ExecuteTextQueryAsync("Select * from LargeNumberOfRowsTable", newConnection, dt); });
                }

Как я уже сказал, я подтвердил, что результаты правильно считываются из базы данных, однако обработчик событий для TableNewRow никогда не срабатывает.

Возможно ли, чтобы другой поток запускал события в вызывающем потоке?

Я совершенно не на том пути для чтения результатов и обновления таблицы по мере их поступления? Я чувствую, что я близок, но мое отсутствие знаний о нитях подводит меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...