Конференция "Начинающим" » Запись в ListBox через Thread [D2005, 2003]
 
  • NIIL © (16.11.18 22:43) [0]
    Доброго времени суток.
    Словил ошибку 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;
  • niil © (17.11.18 00:57) [1]
    Забыл написать, что создание 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;
  • Styx © (17.11.18 22:38) [2]
    С визуальными компонентами нельзя работать из потоков.
  • sniknik © (18.11.18 10:45) [3]
    > С визуальными компонентами нельзя работать из потоков.
    без синхронизации.
    причем со всеми, а не только с тем с которым по мнению ТС у него проблема.

    вот это вот к примеру
    > CompWebImg := TWebImage.Create(Form1);
    > CompWebImg.Parent := Form1;
    уже проблема.

    +
    если запихнуть вообще все что там с формой общается явно или неявно в синхронизацию, то есть всю показанную обработку, то смысл потока пропадет, синхронизированное выполняется в основном...

    можно TWebImage.Create(nil), если он так работает... и все остальные упоминания формы убрать. или полностью логику менять (скачивать через невизуальные indy к примеру).
 
Конференция "Начинающим" » Запись в ListBox через Thread [D2005, 2003]
Есть новые Нет новых   [134427   +34][b:0][p:0]