WAYFARER писал(а):Alex2013а в чем именно проблема заключается?
Alex2013 писал(а):Причем если запускать код потока последовательно все работает как надо .
Во втором варианте не увидел - ты же для каждого потока создаешь свой экземпляр THttpSend, да?
Упс! Спасибо! Это я точно упустил из виду ... Но там и вариант с
bmp:=NetLoadBMP_PHP(URL,sx,sy); глючит аналогично, а там
httpclient точно отдельный.
Сейчас врезал из программы первый вариант и заставил работать в простом примере где капитально вник во все коллизии.

Главный прикол в том что там "тихой сапой" перегружает уже существующий TImage и это обходит запрет на изменение визуального элемента из потока.(Как это воспроизвести при работе со связкой TListView + TImageList ума не приложу .

) А проблемы и непонятки как выяснилось были в чистке списка потоков.
TNetLoad01.7z Размер: 3,1 МБ
(

Проект изначально под виндовс но можно проверить и в других ос, компилировать только для 32 бит (при компиляции для 64-х бит нет доступа в сеть ) ОС может быть какая угодно .
Зы
Я в курсе что "Очистка списка потоков" у меня сейчас лишняя так как на входе в процедуру стоит
"If not T_End then exit;" но это так сказать "задел на будущее" (В это версии примера "Очистка списка потоков" все равно не работает, потому что при очистке галереи нужно следит за состоянием потоков и не освобождать загружаемый TImage по Free ).
Зы Зы
Код модуля галереи в этом примере эдакое многократно переписываемое "чудовище Франкенштейна " используемое в разных тестовых проектах и к саму примеру отношения не имеет.
Добавлено спустя 1 час 19 минут 48 секунд:WAYFARER писал(а):Alex2013а в чем именно проблема заключается?
Проблема в том что нужно быстро и желательно в фоновом режиме загружать от десятков до сотен миниатюр из интернета и при этом зносить все это в галерею созданную на основе связки TListView + TImageList .... И вот тут и возникает туча неприятностей и не понятностей. Я просто надеялся на то что у кого нибудь есть ссылка на готовый и надежный пример многопроточной загрузки изображений из интернета .
Добавлено спустя 8 часов 15 минут 31 секунду:Типа оптимизация и "обнадеживание"

....
Сейчас там явно куча лишнего кода, но как ни пытался повестить это чудовище не так и смог.
Добавлен обычный таймер (object Timer1: TTimer Enabled = False Interval = 100 OnTimer = Timer1Timer)
+ читает массив, а тестовая галерея только для показа
(Достаточно заменить строку
IM:=Form2.AddPic(ListBox1.Items[I],b); на
IM:=Timage.Create(Nil);IM.Assign(B); и выбросить фрагменты с комментарием "//Только для этого теста" и ее можно выбросить из проекта )
Патч к примеру...
- Код: Выделить всё
procedure TLoadPicThread.Load;
Var
B:TBitmap;
begin
try
B:=RE_NetLoadBMP_PHP(fURL);
if Not FreeOnTerminate then begin
if b.Modified then fIm.Picture.Bitmap.Assign(B);
fIm.Picture.Bitmap.Modified:=b.Modified;
end;
B.Free;
except
end;
end;
procedure TLoadPicThread.Execute;
Var
B:TBitmap;
begin
while (not Terminated) do
If UPDATE then begin
Synchronize(@SLoad);
Load;
T_List[Find]:=nil;
T_UPDATE:=T_UPDATE+1;
if not T_End then
T_End:=T_Count = T_UPDATE;
UPDATE :=False;
FreeOnTerminate := True;
Terminate;
end;
end;
procedure TMform.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled:=False;
Button2Click(Sender);
Sleep(10);
end;
procedure TMform.Button1Click(Sender: TObject);
Var
IM:Timage;
I:Integer;
sIm:TList;
T:TLoadPicThread;
Const B:TBitmap=Nil;
IM_List:TList=Nil;
F:Boolean=False;
FC:Boolean=False;
begin
if Timer1.Enabled or f or not T_end then Begin
Timer1.Enabled:=True;
exit;
end;
//Только для этого теста
If Form2.GetControlIndex(Form2.ScrollBox1)=-1 then
Form2.InsertControl(Form2.ScrollBox1);
//---------------------
F:=True;
FC:=False;
MForm.StatusBar1.SimpleText:=
Format(' %d ',[T_COUNT]);
If b = nil then begin
b:=TBitmap.Create;
b.SetSize(Unit2.ImW,Unit2.ImH);
b.Canvas.Pen.Color:=clRed;
b.Canvas.Line (0,0, Unit2.ImW-1,Unit2.ImH-1);
b.Canvas.Frame(0,0, Unit2.ImW-1,Unit2.ImH-1);
b.Modified:=False;
end;
// Очистка списка картинок ---------------------
if IM_List=Nil then IM_List:=TList.Create;
//Только для этого теста
If Form2.GetControlIndex(Form2.ScrollBox1)<>-1 then
Form2.RemoveControl(Form2.ScrollBox1);
if Unit2.ILst<>Nil then begin
For I:=0 to Unit2.ILst.Count-1 do
Form2.ScrollBox1.RemoveControl(TImage(Unit2.ILst[i]));
sIm:=Unit2.ILst;Unit2.ILst:=TList.Create;sIm.Free;
end;
//----------------------
// Очистка списка потоков ---------------------
if T_List=Nil then T_List:=TList.Create;
If (T_List.Count>0) then
For I:=0 to T_List.Count-1 do
If T_List[i]<>nil then
begin
TLoadPicThread(T_List[i]).FreeOnTerminate:=True;
TLoadPicThread(T_List[i]).Terminate;
end;
T_List.Clear;
///Основная очистка
For I:=0 to IM_List.Count-1 do
begin
Timage(IM_List[i]).Free;;
End;
IM_List.Clear;
//-----------------------
T_Count:=ListBox1.Count;
T_UPDATE:=0; T_End:=True;
FC:=True;
For I:=0 to ListBox1.Count-1 do
begin
MForm.StatusBar1.SimpleText:=
Format('Загрузка картинок найдено %d ',[I+1]);
// IM:=Timage.Create(Nil);
IM:=Form2.AddPic(ListBox1.Items[I],b);
end;
For I:=0 to ListBox1.Count-1 do
begin
MForm.StatusBar1.SimpleText:=
Format('Загрузка картинкок найдено %d ',[I+1]);
IM:= TImage(Unit2.ILst[i]);"//Только для этого теста"
Im_List.Add(Im);
T:=TLoadPicThread.Create(True,Memo1.Lines[I], Im,I );
T.UPDATE:=True;
T_List.Add(T);
//T.Execute;
Sleep(5);
End;
FC:=False; Sleep(10);
if not FC Then
For I:=0 to ListBox1.Count-1 do if not FC Then
TLoadPicThread(T_List[I]).Resume;
//Только для этого теста
If Form2.GetControlIndex(Form2.ScrollBox1)=-1 then
Form2.InsertControl(Form2.ScrollBox1);
//======================
F:=False;
end;
Добавлено спустя 11 часов 2 минуты 1 секунду:"Самообман страшная штука" Увы неожиданно оказалась, что все это безобразие все-же капитально виснет при отсутствии доступа в сеть. Видимо куча потоков тупо "дидосит" открытие сокетов...( В нормальном случае сокеты "не толпятся" слишком сильно )
(В базовом проекте, запуск загрузки галереи при отсутствии доступа в сеть почти исключен, бо вначале читается список миниатюр, а там есть более мнение надежная "ловушка исключений", но все равно не хорошо рассчитывать, что "все всегда будет хорошо" . )
Добавлено спустя 1 час 55 минут 1 секунду:Ну вот теперь что-то как-бы работает и со связкой TListView + TImageList но в "ручном режиме" (По кнопке "тест" ) вообщем видимо придется "освежать" TImageList "по таймеру".
(Иначе теряется весь эффект "Ленивой загрузки" то есть если я нажимаю на кнопку Load 1 или Load 2 то загрузка старой галереи происходит псевдо-мгновенно, а потом уже потоки незаметно "догружают" то что подтормаживает )
Зы
На скрине я специально поймал момент неполной загрузки .
