![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
вызов метода в Thread [D5, D6, D7, D2005, 2000, XP, 2003]
Потокер © (2008-10-01 22:23:00)Есть класс, заведует отправкой по сети данных. В нем есть поток (потомок Tthread), в этом потоке создается сокет и поддерживается соединение с сервером. Задача класса принять от пользователя данные (в параметре метода, например) и передать их потоку, а поток уже передаст по сети. Будет ли безопасной попыткой просто вызвать метод у потока и просто параметром передать туда данные?
Примерно так:
//в доп потоке
procedure TSomeThread.SendStream(St:TStream);
begin
FSocket.Send2Network(St);
end;
//некий класс, у которого есть поток
procedure TSomeClass.SendStream(St:TStream);
begin
FSomeThread.SendStream(St);
end;
//вызываю по кнопочке
SomeClass.SendStream( стрим );
Т.е. например передача данных главному потоку из Execute делается через syncronize, а вот передача "В" поток как синхронизируется?
Сергей М. (2008-10-02 08:30:00) [1]
> создал метод, передаю через него. Нормальный ли это подход?
Само по себе использование метода для передачи объекту неких параметров нормально.
Ненормальным выглядит вызов SendStream в контексте потока, вызвавшего этот метод.
Германн (2008-10-02 03:02:00) [2]Уроки ЮЗ продолжаются!
Кто-бы что-бы не говорил. :)
Юрий Зотов (2008-10-02 02:41:00) [3]1. Критические секции распространяются не на переменные и не на классы. Они распространяются на код.
2. Схема передачи данных из главного потока может быть примерно такой:
type
TMyThread = class(TThread)
private
FData: TMyDataPortion;
protected
procedure Execute; override;
public
property Data: TMyDataPortion read FData write FData;
end;
procedure TMyThreadExecute;
begin
while not Terminated do
begin
CriticalSection.Enter; // Здесь поток будет ждать порцию данных.
try
// Здесь обрабатываем эту порцию данных.
finally
CriticalSection.Leave // Сигнализируем, что можно слать следующую.
end
end
end;
procedure TForm1.SomeMethod;
begin
while not EndOfData do
begin
CriticalSection.Enter; // Синхронизируемся с потоком
try
MyThread.Data := NewDataPortion // Передаем ему порцию данных
finally
CriticalSection.Leave // И разрешаем ее обрабатывать
end
end;
MyThread.Terminate
end;
Потокер (2008-10-01 23:48:00) [4]
> Eraser © (01.10.08 23:19) [5]
Пример с кнопкой просто пример, пробывал и с невизуальным классом (обычный class), вызывал у него property, метод вроде SetValue - все равно AV, отсюда и вопрос. (есстественно я создавал экземпляр перед опытами =) ) А в гуглах растиражированные три статьи в огромных количествах.
Eraser (2008-10-01 23:19:00) [5]> [4] Потокер (01.10.08 23:05)
с визуальными/графическими компонентами все таки лучше работать из основного потока. если нужно поменять значение надписи из доп. потока я бы посоветовал вместо метки использовать TStaticText и передавать ему сообщение из доп. потока.
Потокер (2008-10-01 23:05:00) [6]
> Будет. Потому что этот метод будет выполнен в ВЫЗВАВШЕМ
> потоке. Но это, видимо, не то, что Вы хотели.
Опишу поподробнее.
У меня сервер видеонаблюдения, помимо самого наблюдения у него есть (будет =) ) функция удаленного просмотра, мне нужно с наименьшими задержками отправлять в сеть видеоданные (потому и держится постоянное соединение, если бы единоразово нужно было - в create передал и забыл). Т.е. в основном потоке работа с сокетом часто вызывает "запинание" (особенно при дисконнекте каком нибудь), перенес сетевую часть в доп.поток. Вот теперь встал вопрос о доставлении данных потоку, создал метод, передаю через него. Нормальный ли это подход?
И второй вопрос, если можно, везде написано, чт окритические секции позволяют работать с переменными, если у меня глобально объявлен класс (var bt:tbutton;), я могу в секции сделать bt.caption:='123';? вылетает АВ, значит крит.секции распространяются только на переменные, но не классы?
Сергей М. (2008-10-01 22:52:00) [7]
> Потокер (01.10.08 22:23)
Попытка безопасна всегда.
Опасны результаты действий, вызванных этой самой попыткой.
Городской Шаман (2008-10-01 22:38:00) [8]Да только поток должен создаватся suspended, передватся данные и потом вызывать resume
Юрий Зотов (2008-10-01 22:37:00) [9]> Будет ли безопасной попыткой просто вызвать метод у потока и просто
> параметром передать туда данные?
Будет. Потому что этот метод будет выполнен в ВЫЗВАВШЕМ потоке. Но это, видимо, не то, что Вы хотели.
> передача "В" поток как синхронизируется?
Например, через TCriticalSection. Описание в справке.