-
Доброго времени суток. Словил ошибку EOutOfResources with message 'Unable to insert a line' при обработке строк в TListBox через множественные TThread А точнее:
Объявляем метод create с доп. переменными
type TWebImg = class(TTHread) private WAdr, ImgName: string; StrInd, ImgInd: integer; procedure Sync; protected procedure Execute; override; public constructor Create(CreateSuspennded: Boolean; InParam: string; SInd: integer; IInd: integer); end;
constructor TWebImg.Create(CreateSuspennded: Boolean; InParam: string; SInd: integer; IInd: integer); begin inherited Create(CreateSuspennded); WAdr := InParam; StrInd := SInd; ImgInd := IInd; end;
procedure TWebImg.Sync; var ImgList: TListBox; begin ImgList := (Form1.LGrid1.CellControls[7, StrInd] as TListBox); //Проблема исчезает если убрать строку ниже ImgList.Items[ImgInd] := ImgName; Form1.LGrid1.Cells[8, StrInd] := Form1.LGrid1.Cells[8, StrInd] + 'Image download! '; end;
procedure TWebImg.Execute; var CompWebImg: TWebImage; ImgPath: string; begin CompWebImg := TWebImage.Create(Form1); CompWebImg.Parent := Form1; try CompWebImg.URL := WAdr; except on E: exception do begin Form1.LGrid1.Cells[8, StrInd] := Form1.LGrid1.Cells[8, StrInd] + 'Error getting:' + E.Message + ' '; Exit; end; end; if (not CompWebImg.WebPicture.Empty) and (not CompWebImg.WebPicture.IsGIF) then begin ImgName := GetFileName(WAdr, false, false); ImgPath := GetOutDir(StrInd); CompWebImg.SaveToFile(ImgPath + '\' + ImgName); // Думал, что синхронизация решит проблему, но увы. Synchronize(Sync); end; CompWebImg.Destroy; end;
В основном блоке, создаем экз. потока с доп. переменными в цикле и запускаем его:
for j := 0 to ImgList.Count - 1 do begin WebGetTh := TWebImg.Create(false, ImgUrl, i, j); WebGetTh.FreeOnTerminate := true; WebGetTh.Priority := tpNormal; WebGetTh.Resume; ... end;
-
Забыл написать, что создание TListBox также идет в цикле, перед циклом создания потоков. Данные Номер ListBox и строки в нем передаются дополнительными параметрами при создании потока.
for i := 0 to LCount - 1 do begin ... //Текущий для шага цикла i ImgListBox уже программно создан и лежит на форме (с ним все ОК) for j := 0 to ImgList.Count - 1 do ImgListBox.Items.Add('Downloading'); ...
for j := 0 to ImgList.Count - 1 do begin WebGetTh := TWebImg.Create(false, ImgUrl, i, j); WebGetTh.FreeOnTerminate := true; WebGetTh.Priority := tpNormal; WebGetTh.Resume; ... end; end;
-
С визуальными компонентами нельзя работать из потоков.
-
> С визуальными компонентами нельзя работать из потоков. без синхронизации. причем со всеми, а не только с тем с которым по мнению ТС у него проблема.
вот это вот к примеру > CompWebImg := TWebImage.Create(Form1); > CompWebImg.Parent := Form1; уже проблема.
+ если запихнуть вообще все что там с формой общается явно или неявно в синхронизацию, то есть всю показанную обработку, то смысл потока пропадет, синхронизированное выполняется в основном...
можно TWebImage.Create(nil), если он так работает... и все остальные упоминания формы убрать. или полностью логику менять (скачивать через невизуальные indy к примеру).
|