Форум: "Основная";
Текущий архив: 2003.07.10;
Скачать: [xml.tar.bz2];
ВнизThread поток - метод Synchronize. Качество программы. Найти похожие ветки
← →
Andrey02 (2003-06-28 19:39) [0]Методы и свойства визуальных компонентов могут использоваться в потоке только в рамках вызова метода Synchronize
т.е. чтобы выполнить обычную команду
Memo1.lines.add("111");
приходится писать 2 процедуры и использовать 1 лополнительную переменную
TClassThread = class(TThread)
private
ma_S: String
...
procedure TClassThread._Memo1Linesadd(S: String);
begin
ma_S := S;
Synchronize(DoMemo1Linesadd);
end;
procedure TClassThread.DoMemo1Linesadd;
begin
Memo1.lines.add(ma_S);
end;
Вопрос: можно ли как-то более качественно произвести действия с визуальными компонентами в потоке?
← →
panov (2003-06-29 05:12) [1]Можно использовать критические секции. См. TCriticalSection и RTL_CRITICAL_SECTIION
← →
Ihor Osov'yak (2003-06-29 14:48) [2]2 panov © (29.06.03 05:12)
Критичиские секции для примера Andrey02 (28.06.03 19:39 - не выход.
Так как в даном случае синхронайз гарантирует, что манипуляция с Memo1.lines.add(ma_S) будет выполнятся в основном потоке. Использование критической секции в потоке такой гарантии не даст. Вернее, никакого отношения к этому не имеет. То есть может быть ситуация, что даже поставив в своем потоке критическую секцию, мы не исключим обращение к
Memo1.lines из основного потока в то время, когда мы в потоке будем делать изменение Memo1.lines даже внутри критической секции..
2 Andrey02 (28.06.03 19:39)
Лично я синхронайз не использую никогда. Как альтернатива для вашего случая можно использовать SendMessage к хендлеру формы + соотв. обработчик соотв. сообщения. Так как передаем строку, то используем только SendMessage, а не PostMessage (то есть синхронную посылку команды, а не асинхронную)
← →
Ihor Osov'yak (2003-06-29 15:10) [3]> Вопрос: можно ли как-то более качественно произвести действия с визуальными компонентами в потоке?
VCL написана из расчета работы только в основном потоке. Поэтому и требования синхронайз. Он фактически сводится к SendMessage к окну в главном потоке с последующим выполнением подсинхронайзнутой процедуры в главном потоке. Так почему бы этот SendMessage не пользовать непосредственно? Появляется некоторая гибкость за счет передачи параметров wParam, lParam. И код более наглядный (но это уже имхо). Плюс использование PostMessage, когда допускается или желательна ассинхронная обработка.. Ну и конечно для PostMessage не забывать про синхронизацию, когда это нужно..
← →
Andrey02 (2003-06-29 15:46) [4]> фактически сводится к SendMessage к окну в главном потоке с последующим выполнением подсинхронайзнутой процедуры в главном потоке
а как это будет на примере если требуется передать и сам объект, и действия с как параметры в SendMessage?
т.е. есть Memo1 и Memo2
и сообщение для Memo.
← →
Ihor Osov'yak (2003-06-29 16:05) [5]2 Andrey02 (29.06.03 15:46)
Любой обьект - поинтер, сводится к интежер..
Примерно так:
SendMessage(Form1.handle,WMU_DoIt,integer(pointer(Memo1)),0);
и не приемном конце:
procedure TForm1.WMUDoIT(var Msg: TMessage);
begin
if Msg.WParam=0 then exit;
TMemo(Msg.WParam).ТоЧтоНужно
Естественно, что Memo1 должен еще жить на момент работы TForm1.WMUDoIT..
Наиболее просто это достичь при посылке через SendMessage. При PostMessage могут быть ньюансы, здесь долго рассказывать..
Но. Имхо, передавать обьектные ссылки как параметры сообщенией - то как сказать.. Я думаю, что в большинстве случаев это свидетельствует не о очень хорошо продуманной архитектуре приложения..
← →
Ihor Osov'yak (2003-06-29 16:14) [6]Зы - в теле WMUDoIT кодируешь те же действия, что нужно делать (вместо DoMemo1Linesadd;)
Тогда и окажется, что нужно передавать не обьект, а какие то параметры (строку, вероятнее всего для твоего случая)..
И код будет понятнее - в классе TClassThread не будет методов, которые выполняются в контексте иного потока (раньше таким был DoMemo1Linesadd, он исполняется в контексте главного потока).. По названию WMUDoIT видно, что его обработка инициализируется сообщением, можно в коментариях написать от какого обьекта или потока.. Доступ с TForm1.WMUDoIT к внутренностям TForm1 более природный, чем с метода от TClassThread;
Да, и Form1 тогда необязательно делать видимым для TClassThread, достаточно передать только ее хендлер..
← →
Chlavik (2003-06-29 16:14) [7]Я писал Оболочку на TwinControl и ей с потока отсылал месаги
procedure TUploadThrd.DoOnUploadMsg(Msg:string;MsgType:TUploadMsgType);
var Result:Cardinal;
begin
SendMessageTimeOut(FRecepientHandle,CM_StatusMsg,Integer(Msg),Integer(@MsgType),
SMTO_BLOCK,Msg_Delay,Result);
end;
Лучше юзать SendMessageTimeOut ....
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.07.10;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.007 c