Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
1-31304
maxic
2003-06-26 16:40
2003.07.10
Динамическая загрузка DLL


14-31413
sapsi
2003-06-23 09:00
2003.07.10
---|Ветка была без названия|---


4-31563
Петр
2003-05-11 11:19
2003.07.10
Сообщения на обработку нажатия клавиш


1-31215
Mr.Shadow
2003-06-28 22:46
2003.07.10
Огпаничить Доступ


1-31176
Mishenka
2003-06-27 20:55
2003.07.10
RightClick в Treeview...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский