Как лучше всего показать информацию о прогрессе при использовании ADO.NET? - PullRequest
2 голосов
/ 10 апреля 2010

Я хочу показать пользователю подробную информацию о ходе выполнения при выполнении потенциально длительных операций с базой данных. В частности, при вставке / обновлении данных, которые могут быть порядка сотен КБ или МБ.

В настоящее время я использую в памяти DataTables и DataRows, которые затем синхронизируются с базой данных с помощью вызовов TableAdapter.Update. Это прекрасно работает, но одиночный вызов оставляет мало возможностей для сбора какой-либо информации о прогрессе, чтобы показать пользователю. Я понятия не имею, сколько данных проходит через сеть к удаленной БД или ее прогресс. По сути, все, что я знаю, - это когда Update возвращается и считается завершенным (за исключением любых ошибок или исключений). Но это означает, что все, что я могу показать, это 0%, затем пауза, а затем 100%.

Я могу посчитать количество строк, даже если зайти так далеко, чтобы подсчитать, сколько из них на самом деле изменено или добавлено, и я мог бы даже рассчитать для DataRow его предполагаемый размер на основе типа данных каждого столбца, используя sizeof для таких типов значений, как int и проверка длины для таких вещей, как строки или байтовые массивы. С этим я, вероятно, мог бы определить, прежде чем обновлять, приблизительный общий размер передачи, но я все еще застрял без какой-либо информации о прогрессе после вызова Update в TableAdapter.

Я застрял, просто используя неопределенный индикатор выполнения или курсор ожидания мыши? Нужно ли мне радикально изменить наш уровень доступа к данным, чтобы иметь возможность подключаться к такой информации? Даже если я не могу получить точную информацию о переданных КБ (например, индикатор выполнения загрузки файла веб-браузера), могу ли я хотя бы знать, когда заканчивается каждый DataRow / DataTable или что-то еще?

Как лучше всего показывать такую ​​информацию о прогрессе, используя ADO.NET?

Ответы [ 2 ]

1 голос
/ 10 апреля 2010

Для части SELECT есть полу-решение, которое состоит в том, чтобы сначала выполнить запрос COUNT, чтобы получить количество строк, которые вы ожидаете получить. Это практично, только если запрос COUNT может возвращать результат очень быстро (т. Е. За доли секунды) - с другой стороны, если для запуска требуется несколько секунд, то выполняется само выполнение запроса (в отличие от перечисления результатов). ) может занять больше времени, чем передача данных, и в этом случае вообще не стоит пытаться показывать отдельный индикатор выполнения.

Что касается UPDATE и INSERT - нет, на самом деле не существует простого решения для этого, особенно с использованием TableAdapters. Если у вас есть огромное количество данных для отправки, вы можете рассмотреть возможность использования класса SqlBulkCopy для загрузки в промежуточную таблицу и последующего фактического обновления на сервере. Этот класс предлагает свойство NotifyAfter вместе с событием SqlRowsCopied , которое может дать вам разумное приближение к текущему прогрессу (в этом случае вы уже знаете общее количество строк, так как они ' в памяти).

Это, конечно, потребует значительных изменений по сравнению с вашей текущей реализацией TableAdapter, но система типизированных наборов данных в .NET действительно не была предназначена для обработки наборов записей такого размера по чему-либо, кроме подключения к локальной сети.

Я думаю, что большинство людей просто захотят использовать индикатор прогресса. В настоящее время пользователи ожидают этого; даже если бы вы могли точно предсказать количество строк и скорость передачи данных, вы все равно не представляете, сколько времени потребуется для фактического выполнения запроса, особенно если сервер находится под большой нагрузкой, и, возможно, хуже обеспечить плохие оценки , чем нет оценок.

Если есть реальная вероятность того, что сам запрос (или обновление) займет много времени для запуска на самом сервере, не считая времени на загрузку / загрузку записей, то я бы определенно использовал вместо этого индикатор прогресса выделения. В противном случае ... удачи.

0 голосов
/ 10 апреля 2010

Как сказал Aaronaught - SqlBulkCopy с NotifyAfter должен работать (хотя у меня это работает).

Я не думаю, что это будет "существенным изменением" в вашей текущей реализации DAL ...

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