Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2013.09.15;
Скачать: CL | DM;

Вниз

Проблемы с передачей параметров в поток через TStringList   Найти похожие ветки 

 
Pcrepair ©   (2013-01-04 13:18) [0]

Добрый день. Есть вариант передачи параметров через string

unit Unit1;
var
 Form1: TForm1;
implementation
{$R *.dfm}
uses uLoadPage, uGlobalVar;
(*-----Запуск процесса многопотокой закачки страниц*)
procedure TForm1.Button6Click(Sender: TObject);
var
StrLst:TStringList;
Str:string;
begin
 StrLst:=TStringList.Create;
   StrLst.Text:=Memo2.Text; (*Передаем строки с УРЛ в Перем(аналог части Арр)*)
   Str:=StrLst.Text; (*переносим Список в Строка*)
   StartLoadTHreads(Str); (*Вызов ПРОЦ по запуску потоков закачки страниц*)
 FreeAndNil(StrLst);
end;
++++++++++++++++++++++++++++++++++++++
unit uLoadPage;
interface
uses Classes, Generics.Collections, SysUtils;
Procedure StartLoadTHreads(ListOfUrls:string);

implementation
uses uGlobalVar, uStartTHreadLoader, uThreadLoader;
(*  03.01.2013  Процедура запуска загрузки страниц в потоке*)
Procedure StartLoadTHreads(ListOfUrls:string);
var THread:TStartTHreadLoader;
begin
 THread:=TStartTHreadLoader.Create;
 THread.UrlList:=ListOfUrls; (*передача списка УРЛ в поток*)
 THread.Start;
end;
++++++++++++++++++++++++++++++++++++++
unit uStartTHreadLoader;
interface
 uses Classes, SyncObjs, SysUtils, Generics.Collections;
type
 TStartTHreadLoader = class(TThread)
   private
     FUrlList:string;
   protected
     procedure Execute; override;
     Procedure BeginLoadTHreads(StrListOfUrls:TStringList);
   public
     constructor Create;
     destructor Destroy; override;
     property UrlList:string read FUrlList write FUrlList;
 end;

implementation
uses Unit1, uLoadPage, uGlobalVar;

constructor TStartTHreadLoader.Create;
begin
 inherited Create(True); (*Поток создаем в состоянии «Приостановлен»*)
 FreeOnTerminate := True; (* Поток освободит ресурсы при окончании работы*)
 Self.Priority := tpNormal;
end;

destructor TStartTHreadLoader.Destroy;
begin
 inherited Destroy; (*уточнить, точно это нужно?*)
end;

procedure TStartTHreadLoader.Execute;
var StrLst:TStringList;
begin
 StrLst:=TStringList.Create;
 StrLst.Text:=UrlList; (*восстановление списка из строки*)
   try
     BeginLoadTHreads(StrLst); (*передача спика с УРЛ в ПРОЦ*)
   finally
     FreeAndNil(StrLst);
   end;
end;

Procedure TStartTHreadLoader.BeginLoadTHreads(StrListOfUrls:TStringList);
begin
 //тут много всего, но все работает
end;
end.

+++++++++++++++++++++++++++++++++++
в общем все работает, но приходится вначале СПИСОК переместить в строку, затем, в TStartTHreadLoader.Execute все назад возвращать.
Внимание!! Вопрос: можно ли обойтись без усложнения? без использования string. и как именно это сделать
вообще пробовал вместо string использовать TStringList, но почемуто туда не перемещались данные(строки) ПЕРЕМ всегда была пустой. какой то косяк от то что TStringList объект.


 
DVM ©   (2013-01-04 15:00) [1]


> пробовал вместо string использовать TStringList, но почемуто
> туда не перемещались данные(строки) ПЕРЕМ всегда была пустой.
>  какой то косяк от то что TStringList объект.

Если ты пробовал буквально так:


procedure TForm1.Button6Click(Sender: TObject);
var
StrLst:TStringList;
begin
StrLst:=TStringList.Create;
  StrLst.Text:=Memo2.Text; (*Передаем строки с УРЛ в Перем(аналог части Арр)*)
  StartLoadTHreads(StrLst); (*Вызов ПРОЦ по запуску потоков закачки страниц*)
FreeAndNil(StrLst);
end;


то разумеется, ничего не получится, т.к. после старта потока твоему StrLst делается FreeAndNil


 
sniknik ©   (2013-01-04 15:43) [2]

> Вопрос: можно ли обойтись без усложнения?
конечно, пиши проще... и все.

например
первый шаг, выкидываем все из

procedure TForm1.Button6Click(Sender: TObject);
..var
..StrLst:TStringList;
..Str:string;
begin
..  StrLst:=TStringList.Create;
..  StrLst.Text:=Memo2.Text; (*Передаем строки с УРЛ в Перем(аналог части Арр)*)
..  Str:=StrLst.Text; (*переносим Список в Строка*)
 StartLoadTHreads(Memo2.Text); (*Вызов ПРОЦ по запуску потоков закачки страниц*)
..  FreeAndNil(StrLst);
end;

процедура соответственно
(*  03.01.2013  Процедура запуска загрузки страниц в потоке*)
Procedure StartLoadTHreads(const ListOfUrls: string);
//var THread:TStartTHreadLoader;
begin
//  THread:=
 TStartTHreadLoader.Create(ListOfUrls); //перекрыть, там же создавать лист, и прямо там присваивать
//  THread.UrlList:=ListOfUrls; (*передача списка УРЛ в поток*)
//  THread.Start;
end;


второй шаг
осознаем что и процедура лишняя (раз там всего 1 вызов)
и пишем окончательно -
procedure TForm1.Button6Click(Sender: TObject);
begin
 TStartTHreadLoader.Create(Memo2.Text);
end;


 
sniknik ©   (2013-01-04 15:49) [3]

constructor TStartTHreadLoader.Create;
begin
 inherited Create(True); (*Поток создаем в состоянии «Приостановлен»*)
 FreeOnTerminate := True; (* Поток освободит ресурсы при окончании работы*)
 Self.Priority := tpNormal;
end;

???
а где "резюм"?
... не тот ли ты самый "товарищ" который классы потока использует для кода, и сам Execute вызывает, прямо из основного...
терзают меня смутные сомнения.


 
DVM ©   (2013-01-04 16:03) [4]


> sniknik ©  

он приводит не тот код в котором проблема, а какой то другой, т.к. поведение того, что приведено не соответствует описанию проблем.


 
Pcrepair ©   (2013-01-04 19:55) [5]


> а где "резюм"?
> ... не тот ли ты самый "товарищ" который классы потока использует
> для кода, и сам Execute вызывает, прямо из основного...
> терзают меня смутные сомнения.

резюм уже давно запретили. вместо него старт
и для чего в конструкторе старт?
он тут:
Procedure StartLoadTHreads(ListOfUrls:string);
var THread:TStartTHreadLoader;
begin
THread:=TStartTHreadLoader.Create;
THread.UrlList:=ListOfUrls; (*передача списка УРЛ в поток*)
THread.Start; (*вот тут*)
end;

тут вообще то один поток управляет запуском других потоков(оне тут не показаны, чтоб не смущать обилием кода, но все можно посмотреть на validcoderepo.narod.ru), которые закачивают страницы. вначале потока не было и форма тормозила(там кое где есть Sleep(20);, который совершенно необходим для того чтобы не было загрузки проца на 100% в течении 2...20 сек. пришлось код управления потоками закачки страниц тоже вывести в поток.


 
sniknik ©   (2013-01-04 21:48) [6]

> и для чего в конструкторе старт?
а для чего в конструкторе отключать "старт"? только для того чтобы сделать его вне его.

> тут вообще то один поток управляет запуском других потоков...
это как бы понятно, не понятно зачем писать 10 строк там где легко обойтись одной, и после спрашивать "можно ли проще?".

> вначале потока не было и форма тормозила(там кое где есть Sleep(20);, который совершенно необходим для того чтобы не было загрузки проца на 100% в течении 2...20 сек. пришлось код управления потоками закачки страниц тоже вывести в поток.
не придумывай "сущности" там где без них можно обойтись.


 
Медвежонок Пятачок ©   (2013-01-04 21:48) [7]

Интересно, через сколько лет он догадается, что конструктор виртуален, что его можно перекрыть и сделать свой конструктор с параметром?


 
sniknik ©   (2013-01-04 22:07) [8]

а... вспомнил, по
> ПЕРЕМ всегда была пустой

у тебя "форма тормозила" не от того, что 20 потоков запускал, а от того, что там же, в одной процедуре (обработчике) после запуска еще и ждал их завершения (и "слип" там же был чтобы дождаться)...
т.е. пытался писать линейно но на потоках.
вроде оно.


 
Pcrepair ©   (2013-01-04 22:18) [9]

вот потому то и вынес процедуру управления потоками в отдельный поток
теперь форма не тормозит, хотя это не приципиально, программа все равно уходит в системный трей

что касается где запускать СТАРТ, ну тут кто что ... хочет то лепит
одни так советуют другие этак, и все работает и в том и в другом случае

в букварях то же нет однозначного указания как именно все должно быть.

но речь не об этом.

речь о том как правильно передавать параметры в поток через TStringList а не через string.

по этому вопросу кто что канкретно знает?  ну типа надо в конструкторе создать СПИСОК и тд..


 
Pcrepair ©   (2013-01-04 22:21) [10]

да и самое главное, стоит ли вообще использовать СПИСОК, там вообще сложно получается.
правильно ли усложнять код, но типа делать правильно? или в данном случае лучше не усложнять


 
Медвежонок Пятачок ©   (2013-01-04 22:23) [11]

как правильно передавать параметры в поток через TStringList а не через string.

было:
var mystring : string;
someobject.someproc(mystring);

стало:
var mystrinlist : TStrings;
someobject.someproc(mystrinlist);


 
sniknik ©   (2013-01-04 23:07) [12]

> передавать параметры в поток через TStringList а не через string.
примерно так
procedure TForm1.Button6Click(Sender: TObject);
begin
 TStartTHreadLoader.Create(Memo2.Lines);
end;


 
sniknik ©   (2013-01-04 23:11) [13]

> или в данном случае лучше не усложнять
в любом случае, лучше упрощать.
чем проще получится написать, и в меньшее количество строк, тем проще разобраться после.
p.s. нагромождение простых конструкций/бессмысленных "перекладываний", это тоже сложно.



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

Текущий архив: 2013.09.15;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.006 c
15-1365021003
Юрий
2013-04-04 00:30
2013.09.15
С днем рождения ! 4 апреля 2013 четверг


15-1365197648
Чайник
2013-04-06 01:34
2013.09.15
Нич-чо не понимаю!


15-1365366788
GameOn
2013-04-08 00:33
2013.09.15
Таскание компонентов


2-1356651162
NS
2012-12-28 03:32
2013.09.15
Альфа канал иконки


15-1365366603
Юрий
2013-04-08 00:30
2013.09.15
С днем рождения ! 8 апреля 2013 понедельник