TTimer и TThread

 
0
 
Delphi, Kylix & Pascal
ava
gesper | 25.01.2013, 23:28
Предисловие:

Изучал и пробовал работать с потоками на основе прочтения этой статьи http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1370
А вот эту http://forum.vingrad.ru/forum/topic-60076.html , осилю чуть позже

Сам пост:

Есть дерево, при клике на элементах которого в Image рисуется картинка на основе расчетов. Пока она рисуется интерфейс весит. Решил сделать отдельным потоком(см. ниже), вместо рисования создается поток, и он берет данные о площади для рисования и адрес данных, а потом расчитывает и создает канву нужную, после копирует ее в Image. Проблема в том, что он это делает через раз. Т.е. Что то он расчитает и покажет, а что то нафиг пошлет. Думал, может у меня ошибка в расчете самой картинки, взял таймер, и вместо создания потока стал включать таймер, а в его процедуре запускать так же рисование, в итоге все работает стабильно.

С потоками, разберусь сам, если есть идеи почему не всегда отрисовывается, будет интересно.
Вопрос в основном, а "красиво" ли использовать таймер? Тормоза пропадают, идет почти как отдельный поток, но может где то в чем то хуже?



procedure .... // процедура действий при клике по скиску
begin
//....... обработка клика по списку

          Thread:=TDrawVar3Thread.Create(true);
          Thread.FreeOnTerminate:=true;
          Thread.Priority:=tpNormal;
          Thread.Form:=MainForm;
          Thread.Item:=TAccessoriesLayingInUseItem(Data.Item);
          Thread.Resume;

end;


procedure TDrawVar3Thread.Execute;
begin
  CriticalSection.Enter;
  CanvBitmap:=TBitmap.Create;
  Synchronize(GetImage);
  DrawPreview3(Item,true,CanvBitmap.Canvas,CanvBitmap.Width,CanvBitmap.Height);
  //CanvBitmap.SaveToFile(extractfilepath(paramstr(0))+'test.bmp');
  Synchronize(SetCanvas);
  CanvBitmap.Free;

  CriticalSection.Leave;
end;

procedure TDrawVar3Thread.GetImage;
begin
  CanvBitmap.Height:=MainForm.imgView.Height;
  CanvBitmap.Width:=MainForm.imgView.Width;
  MainForm.imgView.Canvas.Brush.Style:=bsSolid;
  MainForm.imgView.Canvas.Brush.Color:=clGray;
  MainForm.imgView.Canvas.Rectangle(0,0,MainForm.imgView.Width,MainForm.imgView.Height);
end;

procedure TDrawVar3Thread.SetCanvas;
begin
  MainForm.imgView.Picture.Bitmap.Assign(CanvBitmap);
  //MainForm.imgView.Refresh;
  MainForm.imgView.Repaint;
end;
Kommentare (7)
ava
Frees | 29.01.2013, 11:58 #
Таймер убрал зависание потому что у тебя привью рисуется только когда ты остановишься на конкретной ветке и подождешь срабатывания таймера.

Я бы объединил решение с Timer и поток.
Поток имеет смысл если есть вариант что DrawPreview3 будет занимать значительное время.

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

также надо


  CriticalSection.Enter;
  try
    ...
  finay
    CriticalSection.Leave;
  end;


Иначе в случае ошибки навсегда заблокируешь CriticalSection
ava
Illusion Dolphin | 29.01.2013, 16:12 #
Цитата


Проблема в том, что он это делает через раз.



А виной тому третий параметр:

DrawPreview3(Item,true,CanvBitmap.Canvas,CanvBitmap.Width,CanvBitmap.Height);


Нельзя в потоке отличном от главного лазить в Canvas. Зато можно работать через Scanline[]
ava
Frees | 29.01.2013, 18:49 #
Цитата (Illusion Dolphin @  29.1.2013,  19:12 findReferencedText)
Нельзя в потоке отличном от главного лазить в Canvas. 

А то что это canvas создан в этом же потоке, не дает на это право?
ava
Illusion Dolphin | 29.01.2013, 22:05 #
Цитата


А то что это canvas создан в этом же потоке, не дает на это право? 


По моему опыту - не даёт. По крайней мере при использвании TBitmap/TBitmapCanvas. Если кто докажет обратное буду признателен.
ava
gesper | 29.01.2013, 23:53 #
Цитата (Illusion Dolphin @  29.1.2013,  16:12 findReferencedText)
ельзя в потоке отличном от главного лазить в Canvas. Зато можно работать через Scanline[]

Режешь без ножа.

Рисовать через таймер удобнее, а потом когда сделал рисование не напрямую в TImage, а сначало создав TBitmap, отрисовав на его канве, а потом присвоив ее уже в TImage, получилось еще быстрее  smile  Кода больше, но работает быстрее smile
ava
Illusion Dolphin | 30.01.2013, 00:27 #
Цитата


а сначало создав TBitmap, отрисовав на его канве, а потом присвоив ее уже в TImage, получилось еще быстрее


Ну если надо ещё быстрее то надо удалить лишние преобразования. Как минимум присвоение в TImage это кашмашно медленная операция.
ava
gesper | 31.01.2013, 21:58 #
Цитата (Illusion Dolphin @  30.1.2013,  00:27 findReferencedText)
Ну если надо ещё быстрее то надо удалить лишние преобразования. Как минимум присвоение в TImage это кашмашно медленная операция.

Сам понял что сказал?)
Если ты не понял моих слов - обработка картинки и передача ее через

imgView.Picture.Bitmap.Assign(TempCanvBitmap);

ускоряет процесс появления нужной картинки на экране.
Registrieren Sie sich oder melden Sie sich an, um schreiben zu können.
Unternehmen des Tages
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Mitwirkende
advanced
Absenden