Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Вызов процедуры в другом потоке с параметрами [Win2k, WinXP]


Страницы:   1 2

__DATA__ ©   (2006-03-01 11:27:00) 

Как вызвать процедуру в другом потоке с параметрами?

Делаю так :


procedure TForm1.Button1Click(Sender: TObject);
 procedure WBNavigate(URL: String);
 begin
   URL := URL;
 end;
var
 s: String;
 c: Cardinal;
begin
 s := 'www.rambler.ru';
 CreateThread(nil,SizeOf(s),@WBNavigate,@s,0,c);
end;


Но в процедуре WBNavigate переменная URL = '', хотя в ней должно было быть 'www.rambler.ru'. Почему значение переменной в процедуру не передается?
И еще как передать в поточную процедуру несколько параметров?


GrayFace   (2006-03-30 10:30:00) [1]

Передавай адрес record'а, в котором все это содержится. Или включай их в наследника TThread.


fobos   (2006-03-27 10:32:00) [2]

Народ ... я хотел бы у Вас поитересоваться, ктонит знает как вызвать процедуру с неколькими параметрами к примеру MyProc(mems:TStringList;login:string;fp:conf;crypt:Word;path,ver:string); где fp - это тип используемый программой ... ?


GrayFace   (2006-03-06 15:35:00) [3]

Резницы нет только если сразу с PChar'ом работать. А если вначале сделать строку, потом выделить память и переписать ее туда, то выделение и переписывание можно сэкономить.


Leonid Troyanovsky   (2006-03-06 15:20:00) [4]


> GrayFace ©   (06.03.06 13:14) [29]
> Еще экономия времени на выделение и копирование памяти!


Нет никакой экономии. То, что оно делается неявно -
не означает, что выделения и освобождения нет.

--
Regards, LVT.


GrayFace   (2006-03-06 13:14:00) [5]

Еще экономия времени на выделение и копирование памяти! =) А мне наоборот нравятся подобные хитрости.
Делал я ради интереса отложенную загрузку на Delphi - вот это вышло самое то - оптимально, компактно, красиво и абсолютно нечитаемо! Хотя, учитывая задачу, читаемость вышла вполне приемлемая.


Leonid Troyanovsky   (2006-03-06 09:35:00) [6]


> GrayFace ©   (04.03.06 15:01) [27]

> Финализация происходит в конце WBNavigate. В момент "<--
>  1" в переменную s записывается переданная строка без увеличения
> счетчика ссылок (остается 1),


В переменную s просто записывается указатель (на раннее выделенную,
но неуничтоженную строку). Поэтому и не происходит никаких изменений
в ранее распределенном блоке, содержащем количество распределенных
байт, длину и счетчик ссылок, да и в самой строке).
Также понятно, как удается обмануть финализацию, бо наличие nil в
s интерпретируется как отсутствие у строки распределенного блока
размером 12+length.
Т.е., механизм этого стал понятен после [21] (зуб спасен ;)

Но, в общем-то, понятно, что этот способ ничем не лучше простого
GetMem с последующим освобождением в функции потока.
Бо, экономия пары строк кода ведет к полной его нечитаемости.

--
Regards, LVT.


GrayFace   (2006-03-04 15:01:00) [7]

> Leonid Troyanovsky ©   (03.03.06 19:11) [25]
> Ну, да. Рабочим его делает отложенная финализация,
> сроки наступления которой еще требуют уточнений.

Финализация происходит в конце WBNavigate. В момент "<-- 1" в переменную s записывается переданная строка без увеличения счетчика ссылок (остается 1), а при завершении WBNavigate строка финализируется, т.к. на нее указывает переменная s.


Fay   (2006-03-03 19:14:00) [8]

2 begin...end ©   (03.03.06 19:05) [24]
> См. код System.ThreadWrapper
Смотрел. Не понял 8(.


Leonid Troyanovsky   (2006-03-03 19:11:00) [9]


> begin...end ©   (03.03.06 18:47) [21]

> Что некорректно? Пользоваться рабочим указателем?
..
> Этот пример не соответствует [8]. В [8] предотвращается
> финализация строки.


Ну, да. Рабочим его делает отложенная финализация,
сроки наступления которой еще требуют уточнений.

Для трех строчек кода неплохой результат, но для пятницы - тяжело.
Ладно, считай - зуб ты отстоял :)

--
Regards, LVT.


begin...end   (2006-03-03 19:05:00) [10]

> Fay ©   (03.03.06 18:59) [23]

В организации обработки исключений, например. См. код System.ThreadWrapper.


Fay   (2006-03-03 18:59:00) [11]

2 begin...end ©   (03.03.06 18:47) [21]
> И дело не только в IsMultiThread.
А в чём ещё?


Leonid Troyanovsky   (2006-03-03 18:48:00) [12]


> Fay ©   (03.03.06 18:40) [20]

> > От чего же?
> Да хоть в файле проекта


Самый, IMHO, верный способ забыть о чем-то,
положить именно это туда.

Однако, замечание принято.
Хендлы надо закрывать всегда, а особенно - в учебных целях.

--
Regards, LVT.


begin...end   (2006-03-03 18:47:00) [13]

> Leonid Troyanovsky ©   (03.03.06 18:07) [16]

> Потому, как некорректно.
Что некорректно? Пользоваться рабочим указателем?

> Рассмотрим следующий случай: ...
Этот пример не соответствует [8]. В [8] предотвращается финализация строки.

> Fay ©   (03.03.06 18:40) [20]

Уже неоднократно говорилось, что в Delphi следует использовать BeginThread вместо CreateThread. И дело не только в IsMultiThread.


Fay   (2006-03-03 18:40:00) [14]

2 Leonid Troyanovsky ©   (03.03.06 18:37) [19]
> От чего же?
Да хоть в файле проекта


Leonid Troyanovsky   (2006-03-03 18:37:00) [15]


> Fay ©   (03.03.06 18:16) [18]

> Дык IsMultithread может и не упоматься именно в этом участке
> кода.


От чего же?
Для таких сочетаний как String & CreateThread оно вовсе не лишне.

--
Regards, LVT.


Fay   (2006-03-03 18:16:00) [16]

2 Leonid Troyanovsky ©   (03.03.06 18:11) [17]
> Никто не говорил и про IsMultithread.
Дык IsMultithread может и не упоматься именно в этом участке кода.


Leonid Troyanovsky   (2006-03-03 18:11:00) [17]


> Fay ©   (03.03.06 17:48) [14]
> Никто, кажется, не упомянул, что CreateThread - функция.


Никто не говорил и про IsMultithread.
Но, в данном случае, не до утечки хендлов.

--
Regards, LVT.


Leonid Troyanovsky   (2006-03-03 18:07:00) [18]


> begin...end ©   (03.03.06 17:13) [12]

> Зуб давать, конечно, не буду, но не вижу причин, по которым
> указанный способ в данном случае может быть нерабочим. Строка
> s при выходе из обработчика Button1Click не будет финализирована,
>  и в поточную функцию передастся рабочий указатель на тело
> константной строки (плюс длину и счётчик ссылок, который
> -1). Почему бы этим указателем не воспользоваться внутри
> функции?


Потому, как некорректно.

Рассмотрим следующий случай:

function WBNavigate(P: PChar): LongInt; stdcall;
begin
 Sleep(5000);
 MessageBox(0, p, nil, 0);
end;

procedure TForm1.Button1Click(Sender: TObject);
var s: String;
с: DWord;
begin
 s := IntToStr(GetTickCount);
 CreateThread(nil, 0, @WBNavigate,Pointer(s),0,с);
end;


Т.е., если нажать несколько раз в течении 5 сек, мы получим
несколько боксов с _одним_ временем (каким?).
Ну, а про изменение s после CreateThread и говорить не стоит.
Если же речь о константе, то ее и не следует рядить в стринг.

--
Regards, LVT.


begin...end   (2006-03-03 17:56:00) [19]

> Fay ©   (03.03.06 17:46) [13]

> При выходе - это после выхода?

При выходе -- это в процессе выхода.

> А до какого момента?

В данном случае (в случае константной строки) -- до момента завершения процесса (причём даже если убрать последнюю строку обработчика из [8]). А в других случаях (например, когда счётчик ссылок у строки, объявленной в обработчике, будет равен 1, а не -1) -- до момента завершения функции потока, вероятно.

Тем не менее, просьба не считать меня приверженцем способов типа [8].


Fay   (2006-03-03 17:48:00) [20]

Никто, кажется, не упомянул, что CreateThread - функция.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо