Библиотека позволяет работать с доп. потоками в привычном для делфи режиме в стиле компонентов.
Проверена работа в следующих сочетаниях: WinCE 5, Windows XP/7, Ubuntu 14, 16LTS, Delphi 7/XE2/XE3, Lazarus 1.6, 1.7.
Некоторые пользователи успешно проверили так же на Win10, OpenSuse. На FreeBSD не взлетело, пока возможности исправить это у меня нет.
Можно обойтись и без компоненты TWChread, воспользовавшись классом TWThread, оберткой над которым компонент и является.
Суть компоненты проста: TWCThread - это поток, который включает в себя любое количество TTAsk, которые выполняются в контексте этого пока.
Вкратце TTask это сообщение для потока. И отработают таски именно в том порядке, в котором их запустить.
Так же добавлен модуль для безопасного логирования в многопоточном окружении (wlog).
У TTask объявлены следующие события:
OnExecute - это событие выполняется в контексте дополнительного потока. Отсюда лучше не трогать VCL/LCL, либо с пониманием и осторожностью.
В него передаются const Msg и var Param (variant) от процедуры Start.
OnFinish - выполняется по завершению OnExecute в контексте основного потока. Здесь так же имеются параметры const Msg и const Param, которые связаны с OnExecute. Их можно анализировать (в OnExecute параметр можно менять, а здесь анализировать).
OnProgress - выполняется в основном потоке. см PostProgress. Есть параметр Msg.
OnMessage - выполняется в основном потоке. см PostMessage. Есть параметры Msg и Param (variant).
У потока можно задавать AffinityMask и менять приоритет.
Перед уничтожением формы, где расположен компонент потока необходимо выполнять этот код:
- Код: Выделить всё
procedure TfrmMain.FormDestroy(Sender: TObject);
begin
WCThread1.FinishAllTasks;
Который прекращает работу текущей задачи (если таковая имеется) и ждет её аварийного завершения.
В архиве так же есть несколько демок.
Для демки фоновой генерации картинок (эмуляция фоновой печати) в модуль LR_Class.pas пакета laszReport необходимо внести некоторые правки.
А именно добавить опцию roMultithread, которая позволит отключить вызов Application.ProcessMessages из других потоков.
После добавления опции так же нужно добавить процедуру procedure DoApplicationProcessMessages;
- Код: Выделить всё
procedure TfrReport.DoApplicationProcessMessages;
begin
if (not (roMultithread in Options)) or (csDesigning in ComponentState) then
Application.ProcessMessages;
end;
И во всем модуле заменить вызов Application.ProcessMessages на следующий код:
- Код: Выделить всё
if Assigned(CurReport) then
CurReport.DoApplicationProcessMessages;
В архиве имеется готовый модуль LR_Class.pas, который является последним на данный момент (27.10.2016) взятым с github из пакета lazReport.
Теперь после отключения ShowProgress и выставления roMultithread ваш отчет может формироваться в другом потоке.
[28.10.2016]
LazReport (демка) прекрасно работает в Windows, а в никсах - никак.
Поправил пару мелких баков.
[13.04.2017]
Убрал StopThread (Terminate удобнее).
Добавил возможность стартовать поток 2 из потока 1 с обратной связью в поток 1 (а не VCL/LCL).
Тут нужно понимать, что используется механизм сообщений и обратная связь идет через очередь потока 1.
Убрал жуткую ошибку, которая тянулась с самого начала, но вылезла только на стресс-тесте в внезапным закрытием, когда потоки во всю "общаются".
Ну и исправления по мелочи...
[10.07.2017]
Убрал архив, залил на гитхаб: https://github.com/wadman/wthread/
Из последних изменений: поток для синхронного вызова vcl/lcl перевел в режим singleton.
Как раньше не догадался? При большом количестве потоков большой и не нужный расход памяти и дескрипторов.
Теперь таски по умолчанию принудительно прибиваются при Destroy (выставлением соответствующего флага, в таске это проверяется Terminated), если не вызвать явно ожидание их работы (FinishAllTasks, WaitAllTasks). Раньше было наоборот.