Как правильно обращаться с процедурами, выполнение которых занимает «много времени»? - PullRequest
0 голосов
/ 31 октября 2008

У меня есть приложение Winforms, созданное в Visual Studio 2005 Pro, оно подключается к базе данных SQL Server 2005, используя классы SqlConnection / SqlCommand / SqlDataAdapter для извлечения данных. Я сохранил процедуры в своей базе данных, чтобы вернуть мне данные.

Каков наилучший способ обработки запросов, выполнение которых занимает «много времени»? (то есть достаточно долго, чтобы пользователь начал думать, что что-то не так). В настоящее время мое приложение блокируется до тех пор, пока запрос не будет завершен или не истечет время ожидания запроса. Очевидно, это недопустимо.

Я бы по крайней мере хотел бы индикатор прогресса с кнопкой "стоп" на нем. Измеритель прогресса даже не должен делать ничего полезного, достаточно намека на терпение и ожидание.

Еще лучше было бы предупреждение, в котором говорилось бы что-то вроде: «Это вернет 140 000 строк данных. Вы хотите продолжить?»

Я знаю, что это, вероятно, требует темы, но как?

Ответы [ 8 ]

3 голосов
/ 31 октября 2008

Простой пример C # 2.0:

    private void Form_Load(object sender, EventArgs e)
    {
        BackgroundWorker bw = new BackgroundWorker();
        bw.DoWork += new DoWorkEventHandler(bw_DoWork);
        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
        //change UI to reflect we're doing this
        bw.RunWorkerAsync();
    }

    void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        //SQL Work
    }

    void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        //Let the user know we're done
    }
3 голосов
/ 31 октября 2008

Убедиться, что запросы оптимизированы, - это первый шаг, но после этого вам придется использовать многопоточность, и .NET имеет компонент * BackgroundWorker * для этих случаев.

Вот полный пример

1 голос
/ 31 октября 2008

Я использую RunWorker и ProgressBar при создании длинных файлов.

Одна хитрость, которую я использую, - это найти прокси, длину файла, используемую при настройке ProgressBar. Например, ProgressBar может основываться на числовых строках в файле, когда последний раз выполнялась функция (возможно, в длинном файле). ProgressBar или аналогичный не обязательно должен быть точным.

1 голос
/ 31 октября 2008

Хорошо, во-первых, я бы посоветовал попытаться сделать запросы быстрее. Первое, что нужно проверить, это убедиться, что у вас есть соответствующие индексы. В Интернете множество статей об использовании индексов.

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

С помощью курсора вы читаете результаты по одному и вытягиваете их. Это даст вам возможность отобразить индикатор выполнения.

Если вы придерживаетесь своей текущей модели запросов и просто используете потоки для рисования индикаторов выполнения, ваши индикаторы не будут иметь отношения к выполняемой работе и будут выглядеть неправильно.

0 голосов
/ 01 декабря 2008

Для вашего индикатора прогресса, посмотрите на стиль Marquee. Если по какой-то причине нецелесообразно получить реальный отчет о ходе работы (то есть, если использование CURSOR, как предлагает dicroce, оказывается несостоятельным / слишком медленным / каким-либо другим способом), вы можете использовать индикатор выполнения Marquee, чтобы показать, что ваш пользовательский интерфейс все еще отвечает и вы не забыли о пользователе.

Помните правило Якоба Нильсена: если вам потребуется более 250 мс (?), Чтобы вернуться к пользователю, они будут беспокоиться, что что-то не так. Как правило, ваша кнопка должна выполнить любую необходимую проверку (быстро!), Затем показать что-то, что говорит пользователю «Я работаю», и вернуть управление в цикл пользовательского интерфейса.

0 голосов
/ 31 октября 2008

Вы захотите воспользоваться Threading. Когда пользователь сигнализирует о необходимости извлечения данных, вы можете создать новый поток для извлечения данных, в то же время делая пульсатор видимым в главной форме. Когда поток возвращается, вы можете реагировать и показывать результаты.

0 голосов
/ 31 октября 2008

Возможно, вы захотите создать другую таблицу для регистрации времени выполнения запроса. Таким образом, вы можете сказать: «В прошлый раз этот процесс занял X количество времени». Это даст им приблизительную оценку того, сколько времени это займет. В противном случае вам придется выполнить запрос, чтобы получить COUNT, который, вероятно, сам по себе займет много времени.

0 голосов
/ 31 октября 2008

Для реализации вашего предупреждения вы можете сначала выполнить запрос COUNT (), который не только вернет число строк, которые пользователь должен получить, но и может начать кэшировать данные.

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