Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2002.03.28;
Скачать: [xml.tar.bz2];

Вниз

TThread   Найти похожие ветки 

 
lipskiy   (2002-03-16 01:23) [0]

Два вопроса.
1. Метод Synchronize почему нельзя вызвать из основного потока?
2. Если делаю так:

constructor TSomeThread.Create;
begin
inherited Create(True);
FreeOnTerminate:= True;
Self.Priority:= tpHigher;
SomeComponent:= TSomeComponent.Create;
SomeComponent.OnEvent:= SomeCompEvent;
Resume;
end;


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

А вот если две строчки
SomeComponent:= TSomeComponent.Create;
SomeComponent.OnEvent:= SomeCompEvent;

перенести внутрь Execute - в самое начало, то все работает безошибочно. А чем первый-то вариант может быть плох?


 
kull   (2002-03-16 02:03) [1]

1. Вообще то Synchronize защищенный метод класса TThread поэтому его можно вызвать только из потомка.
Или переписать его в потомке в секции public.

А в принципе Synchronize и существует для того чтоб вызывать его не из основного потока,а из своего потока. Иначе нет никакого смысла.

2. А здесь я что-то не понял, может еше раз поподробнее?


 
lipskiy   (2002-03-16 02:16) [2]

Насчет вызова Synchronize, в принципе, понятно, конечно, но вот в хелпе написано:
If you are unsure whether a method call is thread-safe, call it from within the main VCL thread by passing it to the Synchronize method.
Здесь main VCL thread разве не основная программа?
Ну а на практике потребовалось это вот зачем.
Есть, например, компонентик для закачки файлов с инета. Он создан в дизайн-тайме (невизуальный) и лежит просто на главной форме. Так вот и получается, что я не могу им нормально воспользоваться в потоке в этом случае. А получается только если создавать его вместе с потоком в ран-тайме.

А насчет второго вопроса... Ну, поробую, я и сам ни фига не понял, что произошло.
Так вот, перенес я создание этого компонента для закачки файлов в конструктор потока и стал прогонять. Файл скачался, все ок. Поток завершился, никаких ошибок. Теперь не закрывая программы просто вызвал окно проводника или аську запустил (не важно что) - и моя прога выдает (вернее - Дельфа) что "неверный дескриптор окна" и вываливается совсем.
Решил создать компонент (ну то есть его экземпляр, или как это правильно говориться) не в конструкторе потока, а внутри Execute - перед тем, как собственно стартовать закачку. И вот после этого прога работала без глюков как положено.
Причины я так и не понял.


 
kull   (2002-03-16 02:28) [3]

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


 
lipskiy   (2002-03-16 02:54) [4]

А как, например, если компонент создан в основном потоке, а обрабатывается в отдельном, и у компонента есть событие, которое возникает периодически во время работы (прогресс закачки, например), так вот как из обработчика этого события вызвать Synchronize - ведь сам обработчик находится в основном потоке?


 
kull   (2002-03-16 03:06) [5]

Прогресс закачки, я так понимаю вызывается из потока закачки,
а это значит, что событие обрабатывается не в основном потоке.

Я дела примерно так:

1. создал поток в который передал метод формы.
2. в Execute вызывал этод метод, в котором и велась работа с базой, а также устанавливался индикатор прогресса через Synchronize (его я переопределил как public).


 
lipskiy   (2002-03-16 11:23) [6]


> 1. создал поток в который передал метод формы.

Это как? (не проснулся я еще, что ли...)


 
kull   (2002-03-16 16:03) [7]

Ну примерно так:

//unit с потоком


unit Unit2;

interface

uses
Classes;

type
TMyMethod = procedure(Sender:TThread) of object;

TMyThread = class(TThread)
private
{ Private declarations }
FMyMethod: TMyMethod;
protected
procedure Execute; override;
public
constructor Create(MyMethod: TMyMethod); reintroduce;
procedure Synchronize(Method: TThreadMethod);
end;


implementation


{ TMyThread }

constructor TMyThread.Create(MyMethod: TMyMethod);
begin
FMyMethod:=MyMethod;
inherited Create(False);
end;

procedure TMyThread.Execute;
begin
{ Place thread code here }
FMyMethod(Self);
end;

procedure TMyThread.Synchronize(Method: TThreadMethod);
begin
inherited Synchronize(Method);
end;


//unit c формой
uses .......,Unit2;//подключаю мой Thread

TForm1 = class........
.............
//метод
procedure MyFormMethod(Sender:TThread);
............
end;

...........
..........

procedure TForm1.MyFormMethod(Sender:TThread);
begin
while not TMyThread(Sender).Terminated {Terminated тоже можно сделать public или завести свой флаг на форме} do
begin
загрузка данных с периодическим вызовом
TMyThread(Sender).Synchronize(MyProgressMethod);
end;
end;



 
lipskiy   (2002-03-16 16:20) [8]

Угу, спасибо, понял принцип.
То есть не напрямик вызывать Synchronize из основного потока, а правой пяткой через левое ухо :)
Да не, нормально. Так и сделаю.


 
kull   (2002-03-16 16:23) [9]

Ну я рад, что чем то помог...



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2002.03.28;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.005 c
14-91066
lel (A)
2002-02-14 12:11
2002.03.28
Поздравляю всех с днем влюбленных!!!!!!!!


4-91100
Leo^Sun
2002-01-28 07:48
2002.03.28
Помогите с окнами...


1-90948
HELP!!!!!!!!!!!!!!!
2002-03-14 16:23
2002.03.28
!!!!!!!!!!!!!!!!!!


4-91132
Itspets
2002-01-27 20:41
2002.03.28
API функция есть в NT, но нет в Win9x


6-91029
Елена3000
2002-01-11 23:43
2002.03.28
Disconnect ~ Connect





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский