Форум: "Начинающим";
Текущий архив: 2013.09.15;
Скачать: [xml.tar.bz2];
ВнизПроблемы с передачей параметров в поток через 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;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.002 c