Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите с потоком! (ошибка синхронизации?) 
:(
    Опции темы
Illusion Dolphin
  Дата 7.2.2004, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1198
Регистрация: 3.5.2003

Репутация: 36
Всего: 63



Я заношу из базы данных в TListView данные, и подгружаю к итемсам картинки. Сначала я всё делал в основном потоке, и ошибок не взникало, но было подтомраживание, неудобсва, поэтому я решил вынести часть кода, который загружает картинки, в отдельный поток. Тут и полезла одна ,но очень странная ошибка: EOutOfResources with message 'The reauested resource is in use'. Если во время загрузки ничего не делать с TListView , то вроде всё нормально, но если его скроллишь, или ещё что-нибудь делаешь (толком я не понял), то иногда возникает эта ошибка... Судя по тексту ошибка может тут поток юзает что-то, пока это занято основным потоком? Но что?
Привожу мини-приложение, где возникает ошибка (есть только это, ничего не вырезал на всякий случай)

Код

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, DB, DBTables, StdCtrls, ComCtrls, ExtCtrls, ImgList;

type
 TForm1 = class(TForm)
   DataSource1: TDataSource;
   Query1: TQuery;
   Image1: TImage;
   ListView1: TListView;
   Edit1: TEdit;
   Button1: TButton;
   Button2: TButton;
   ImageList1: TImageList;
   procedure Button1Click(Sender: TObject);
procedure additem_(sender: TObject; Name_ : String; tag : integer );
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;
 thum_images_:integer;

 const dbname =  'D:\DolphinImages.DB';

implementation

uses Searchthread;

{$R *.dfm}

procedure tform1.additem_(sender: TObject; Name_ : String; tag : integer );
var new:tlistitem;
begin
new := ListView1.Items.Add;
new.Indent:=tag;
new.Caption:=Name_;
end;

procedure TForm1.Button1Click(Sender: TObject);
var sqltext,sqlquery:string; i:integer;
begin
ListView1.Clear;
ImageList1.Clear;
sqltext:=edit1.text;
sqlquery:='SELECT * FROM "'+dbname+'"';
sqlquery:=sqlquery+' WHERE FileName like '''+sqltext+'''';
Query1.sql.text:=sqlquery;
Query1.active:=true;
Query1.First;
for i:=1 to Query1.RecordCount do
begin
additem_(sender, Query1.FieldByName('Name').asstring, Query1.FieldByName('ID').asinteger );
Query1.Next;
 end;
 Search_thread.Create(false);
end;

end.


и сам поток:

Код

unit Searchthread;

interface

uses
Dialogs, Classes,DBGrids,DB, DBTables,  SysUtils,ComCtrls, Graphics, jpeg;

type
 Search_thread = class(TThread)
 fitem: TListItem;
 findex:integer;
 fbit:Tbitmap;
 fpic:tpicture;
 fQuery: TQuery;
 fDataSource: TDataSource;
 private
 procedure  setimageindex;
 procedure addimagetolist;
   { Private declarations }
 protected
  procedure Execute; override;
 end;

implementation

{ Search_thread }

uses Unit1;

procedure Search_thread.setimageindex;
begin
fitem.ImageIndex:=findex;
end;

procedure Search_thread.addimagetolist;
begin
try
form1.ImageList1.Add(fbit,nil);
except
on E: Exception do
begin
Search_thread.Create(true);
showmessage(E.Message);
end;
end;
end;

procedure Search_thread.Execute;
  var  fbs:TBlobStream;
  i:integer;
begin
 fQuery:=TQuery.Create(nil);
 fDataSource:=TDataSource.Create(nil);
 fDataSource.DataSet:=fQuery;
 fQuery.DatabaseName:='DolphinAlias';
 fbit:=Tbitmap.create;
 fbit.PixelFormat:=pf24bit;
 fbit.Width:=100;
 fbit.Height:=100;
 fbit.Canvas.Brush.color:=clwhite;
 fbit.Canvas.pen.color:=clwhite;
 fpic:=tpicture.create;
 fpic.Graphic:=TJPEGImage.Create;
 fbit.canvas.rectangle(0,0,100,100);
 fbit.canvas.Draw(50 - form1.image1.picture.Graphic.Width div 2,50 - form1.image1.picture.Graphic.height div 2,form1.image1.picture.Graphic); //картинка по умолчанию, пока не загрузилось то, что надо
 Synchronize(addimagetolist);
 thum_images_:=0;
with form1 do
 begin
 for i:=1 to listview1.Items.Count do
 if listview1.Items[i-1].ImageIndex=0 then
 begin
 try
 fQuery.Active:=false;
 fQuery.sql.text:='SELECT * FROM "'+dbname+'"'+' WHERE ID='''+inttostr(listview1.Items[i-1].Indent)+'''';
 fQuery.active:=true;
 except
  Showmessage('Point 1')
 end;
 try
  fbs:=TBlobStream.Create(TBlobField(fQuery.FieldByName('thum')),bmRead);
  if fbs.Size<>0 then
  fpic.Graphic.loadfromStream(fbs);
  fbs.Free;
 except
  Showmessage('Point 2')
 end;
 try
fbit.canvas.rectangle(0,0,100,100);
fbit.canvas.Draw(50 - fpic.Graphic.Width div 2,50 - fpic.Graphic.height div 2,fpic.Graphic);
inc(thum_images_);
fitem:=listview1.Items[i-1];
findex:= thum_images_;
 except
  Showmessage('Point 3')
 end;
try
Synchronize(addimagetolist);
Synchronize(setimageindex);
 except
  Showmessage('Point 4')
 end;
end;
end;
fbit.free;
fpic.Free;
fQuery.Free;
fDataSource.Free;
end;

end.


ошибка вылетает в addimagetolist, но компилятор её не отлавливает толком, только изза секции try можно мпонять, что ошибка возниикает именно там. Я вроде бы выполнил Synchronize, но что-то тут ещё... Люди, помогите!!!


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
Illusion Dolphin
Дата 8.2.2004, 09:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1198
Регистрация: 3.5.2003

Репутация: 36
Всего: 63



Эх, никто не в курсе... Пришлось разбираться самому. Для тех, кому интересно, что же тут было: всё исправилось изменением процедур в нити:
Код

procedure Search_thread.setimageindex;
begin
fitem.ImageIndex:=thum_images_;
SendMessage(form2.listview1.handle, LVM_SETIMAGELIST, LVSIL_NORMAL, Longint(form2.imagelist1.handle));
end;


и

Код

procedure Search_thread.addimagetolist;
var fmask, fim:tbitmap;
begin
fmask:=tbitmap.create;
fim:=tbitmap.create;
fim.Assign(fbit);
ImageList_Add(form2.imagelist1.Handle,fbit.Handle, fmask.Handle);
fim.Free;
fmask.Free;
end;


Но интересно, как же классифицировать ошибку... Прошлый глюк бы по-моему из-за следующего: при изменении в имэйджлист, как то добавлении лементов), перерисовывалось одновременно содержимое листвьюва, причём это присходило с помощью внутренней процедуры имэйджвьюва change, которая было объявлена как динамическая... По-моему метод синхронизе не очень точно работал с этим динамическим метедом и иногда из-за этого и происходила ошибка. при использовании ImageList_Add имэйджлист не вызывает метод change, и ошибка пропадает...


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0800 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.