Форум: "Основная";
Текущий архив: 2002.01.21;
Скачать: [xml.tar.bz2];
ВнизПотоки Найти похожие ветки
← →
Raven (2001-12-28 17:15) [0]Дело в том, что я стал пользоваться Delphi6 недавно, поэтому вопрос может и простой, но... Короче есть прога и в ней используется TThread, для завполнения дерева(TTreeView). Под Windows9X и Windows ME, всё работает замечательно. Под Windows2000 возникает проблема: Форма, на которой дерево заполняется потоком становится как бы неактивной, то есть всё замирает пока дерево не заполнится, т.е. как в однопоточной модели. Помогите как лечить плз. Заранее благодарен.
← →
Alex_Sudakov (2001-12-28 17:52) [1]Дык это... Код покажи.
← →
Raven (2001-12-29 09:15) [2]Показываю...
unit TVThread;
interface
uses
Classes, comctrls, ADOdb, sysutils, Tools, windows,commctrl,Forms;
type
//описание класса
TTVThread = class(TThread)
private
{ Private declarations }
protected
FTable:TADOTable;
FVisibleFields:TStrArr;
FTV:TTreeView;
FPrimaryKey,FRelationKey:String;
FCaption:String;
FPB:TProgressBar;
FNode:TTreeNode;
procedure Execute; override;
procedure FillTreeVeiw;
procedure _AddNode;
procedure _GetNode;
public
constructor Create(var TV:TTreeView;ATable:TADOTable;PrimaryKey,
RelationKey:String;VisibleFields:TStrArr;ProgressBar:TProgressBar);
destructor Destroy;override;
end;
//
var FT:TTVThread;
implementation
//
uses Explorer,DBDataModule;
{ конструктор, создаёт экземпляр класса, описанного выше, передаёт таблицу БД дерево и ключи для таблице и видимые поля}
constructor TTVThread.Create(var TV:TTreeView;ATable:TADOTable;PrimaryKey,
RelationKey:String;VisibleFields:TStrArr;ProgressBar:TProgressBar);
begin
FreeOnTerminate:=true;
FTV:=TV;
FreeNodesData(FTV);
// очистка дерева
FTV.Items.Clear;
FTable:=ATable;
FTable.Open;
FRelationKey:=Relationkey;
FVisibleFields:=VisibleFields;
FPrimaryKey:=PrimaryKey;
FPB:=ProgressBar;
FPB.Max:=FTable.RecordCount;
FNode:=nil;
inherited Create(false);
end;
//EXECUTE
procedure TTVThread.Execute;
begin
FPB.Show;
FTable.First;
// заполнение дерева
FillTreeVeiw;
FPB.Hide;
end;
//EXECUTE
// получение нужного узла дерева
procedure TTVThread._GetNode;
var i :LongInt;
begin
i:=0;
While not Terminated and (i<=(FTV.Items.Count-1)) and (LongInt(FTV.Items[i].Data^)=FTable.FieldByName(FRelationKey).AsInteger) do
begin
if LongInt(FTV.Items[i].Data^)=FTable.FieldByName(FRelationKey).AsInteger then
FNode:=FTV.Items[i];
end;
end;
//добавление узла дерева
procedure TTVThread._AddNode;
begin
try
if FTable.FieldByName(FRelationKey).Value=0 then FNode:=FTV.Items.Add(nil,FCaption)
else
begin
_GetNode;
FNode:=FTV.Items.AddChild(FNode,FCaption);
end;
FNode.Data:=AllocMem(SizeOf(FTable.FieldByName(FPrimaryKey).AsInteger));
Integer(FNode.Data^):=FTable.FieldByName(FPrimaryKey).Value;
FPB.Position:=FPB.Position+1;
except
end;
end;
procedure TTVThread.FillTreeVeiw;
var i:LongInt;
j:Byte;
begin
try
for i:=0 to FTable.RecordCount-1 do
begin
if Terminated then Exit;
FCaption:="";
for j:=0 to high(FVisibleFields) do
FCaption:=FCaption+" "+FTable.FieldByName(FVisibleFields[j]).AsString;
Synchronize(_AddNode);
if not Terminated then FTable.Next;
end;
except
end;
end;
destructor TTVThread.Destroy;
begin
// try
FTable.Close;
{ except
end;}
inherited Destroy;
// MessageBox(Application.Handle,"
← →
NailS (2001-12-29 14:26) [3]На сколько я вижу, при такой реализации заполнения дерева у тебя все преимущество потока съедается использованием Synchronize, поскольку создание ноды и добавление в дерево происходит в главном потоке.
Как информация к размышлению, попробуй создавать ноду в потоке,
и делать PostMessage в твою форму в параметрах передавай указатель на ноду и родительскую ноду.
Должно работать побыстрее.
← →
Wizard_Ex (2001-12-29 17:47) [4]Я не скажу
to Raven © (28.12.01 17:15)
>>Под Windows2000 возникает проблема: Форма, на которой дерево >>заполняется потоком становится как бы неактивной, ...
Есть такая ерунда и под W2K и под XP
я думаю чего то там подправили немножечько.
Но как лечить??...
← →
yaJohn (2001-12-29 18:08) [5]Kak-kak...
Esli ti rabotaesh s derevom v potoke - znachit do konca obrabotki s derevom mojet rabotat tolko potok (samo soboy est Synchronize, no s nim tormozish osnovnoe prilojenie).
T.e. zadacha - ne dopustit k derevu nikogo do konca raboti potoka. Kak?
1. BeginUpdate (kajetsia tak);
2. Visible:=false;
3. Unichtojenie dereva na kornu, sozdanie rukami s 0, zapolnenie i uje potom - Parent:=self; Izvrat, no nadejno ;)
4. Vopros ne v tom, pochemu pod w2k tormozit, a v tom, pochemu pod w9x ne tormozit... Doljno, voobsheto. ;)
5. Rabota BDE v potoke - delo temnoe i issledovaniu ne podlejit.
Prakticheskiy (ochen) sovet. Ya pochti analogichnuu zadachu (s vizualnim otobrajeniem processa virashivania dereva) reshil v svoe vremia cherez TTimer. Nechto vrode:
Form1._OnTimer(sender: TObject);
begin
Tree.Items.AddChild(nil,Table.FieldByName......
Table.Next;
if Table.Eof then Sender.Free;//podrazumevaetsia dinamicheskoe sozdanie taimera. S samolikvidaciey po zavershenii :)
end;
← →
Raven (2002-01-03 08:46) [6]Уважаемые программеры и yaJohn, в частности я забыл предупредить, но я не с BDE работаю, да и дело не в драйверах БД.
P.S. С Новым Годом!
← →
MrBeer (2002-01-03 09:05) [7]Mozhet nado sdelatj Thread safe versiju etogo samovo tree pri pomoschi EnterCriticalSection ili delfiskovo TCriticalSection, a potom uzhe iz threada zapolnyatj ne bespokojasj... no eto moi imho, vozmozhno tam estj problemi.
Best regards, MrBeer.
← →
Raven (2002-01-03 09:27) [8]Ещё более удивительные события, Господа! Вы не поверите, заработало, почему не знаю. Правда приоритет я Трида низкий поставил, но думаю дело не в этом! Наверное Новый Год помог. Хотя может глючить ещё будет, так что я жду предложений... Спасибо всем кто откликнулся.
← →
Raven (2002-01-03 12:58) [9]Спасибо всем! Действительно приоритет потока оказался слишком высоким по умолчанию. Поставил низкий TThraed.Priority:=tpLowest и всё работает.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.01.21;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.004 c