Заставьте окно обновляться (и т.д.) без вызывающего приложения. ProcessMessages?

Существует большое и исчерпывающее сравнение таблицы и диаграммы на мерзавце, Подвижном и Базар, законченный в руководство InfoQ о DVCS.

14
задан robsoft 17 July 2009 в 09:27
поделиться

4 ответа

Если вы вызовете Update () в элементах управления после изменения свойств, вы заставите их перерисовать. Другой способ - вызвать Repaint () вместо Refresh () , что подразумевает вызов Update () .

Возможно, потребуется вызвать Update () также для родительских элементов управления или фреймов, но это может позволить вам полностью исключить вызов ProcessMessages () .

18
ответ дан 1 December 2019 в 08:53
поделиться

Техника, которую вы ищете, называется многопоточностью . Это сложный метод программирования. С кодом следует обращаться осторожно, потому что его труднее отлаживать. Независимо от того, используете ли вы многопоточность или нет, вам обязательно следует отключить элементы управления, которые пользователи должны , а не возиться с (я имею в виду элементы управления, которые могут влиять на текущий процесс). Вам следует рассмотреть возможность использования действий для включения / отключения кнопок и т. Д.

1
ответ дан 1 December 2019 в 08:53
поделиться

Решение, которое я использую для длительных обновлений, - это выполнение вычислений в отдельном потоке. Таким образом, основной поток остается очень отзывчивым. Как только поток завершен, он отправляет сообщение Windows в основной поток, указывающее, что основной поток может обработать результаты.

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

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

Я сам довольно много раз использовал эту технику, потому что считаю, что она намного лучше. (Но также более сложный.)

8
ответ дан 1 December 2019 в 08:53
поделиться

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

В итоге вы получите что-то вроде

procedure OnClick(Sender:TObejct);
begin
    if (FBusy) then
    begin
        ShowMessage('Wait for it!!');
        Exit;
    end
    else FBusy := True;
    try
        //long running code
    finally
        FBusy := False;
    end;
end;

Невозможно не забыть прорезать долго выполняющийся код в блоке try-finally в в случае выхода или исключения, так как в итоге вы получите форму, которая не будет работать.

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

1
ответ дан 1 December 2019 в 08:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: