Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Опять про потоки... [D6, WinXP]


nikulin ©   (2003-01-22 09:46:00) 

Есть класс потока.
Создаю поток так:

procedure TForm1.Button1Click(Sender: TObject);
begin
Test := TTest.Create(False);
end;

Наблюдаю следующее.
Сразу после старта проги в Task Manager"е в столбце потоки количество потоков 1. Когда поток завершает работу количество потоков остается равным 2. Вроде все удаляю. Откуда берется еще один поток?

**********************************************************
unit Unit2;

interface

uses
Classes, ADODB, Windows;

const
ConnectString = "Provider=SQLOLEDB.1;" +
"Integrated Security=SSPI;" +
"Persist Security Info=False;" +
"Initial Catalog=Abonent;Data Source=cops";

type
TTest = class(TThread)
public
constructor Create(CreateSuspended: Boolean);
destructor Destroy; override;
private
{ Private declarations }
FADOCn: TADOConnection;
FADODataSet: TADODataSet;
protected
procedure Execute; override;
end;

implementation

constructor TTest.Create(CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
Priority := tpNormal;
FreeOnTerminate := True;

FADOCn := TADOConnection.Create(nil);
FADOCn.ConnectionString := ConnectString;
FADOCn.Open;

FADODataSet := TADODataSet.Create(nil);
end;

destructor TTest.Destroy;
begin
FADOCn.Close;
FADOCn.Free;

FADODataSet.Free;
end;


procedure TTest.Execute;
begin
FADOCn.Execute("select null");
MessageBox(0,"","",0);
end;

end.


nikulin   (2003-01-22 13:21:00) [1]

Спасибо Digitman
Попробую так.


Digitman   (2003-01-22 11:16:00) [2]

Каждый поток, осуществляющий доступ к OLE/COM-механизму в режиме котроллера, ОБЯЗАН выполнять обращения к этому механизму вот в таких в "скобках" :

CoInitialize(nil);
try
... работа с OLE/COM
finally
CoUnitialize(nil);
end;

Эти "скобки" неявно присутствуют в коде осн.потока, но в доп.потоке это нужно делать явно.

ADO-механизм базируется на OLE/COM-механизме, так что использование в доп.потоке как компонента ADOConnection, так и методов/св-в любых компонентов, зависящих от ADOConnection, должно сопровождаться этими "скобками", открывающими и закрывающими метод Execute()


nikulin   (2003-01-22 10:51:00) [3]

Попробовал я создавать объект TADOConnection просто так вне потока. После его освобождения остается один поток. Вот так.


Smithson   (2003-01-22 10:40:00) [4]

Стоял я на этих граблях. Похоже, второй поток используется VCL для Synchronize


Digitman   (2003-01-22 10:16:00) [5]

Так ты возьми и проконтролируй, что за потоки работают !
На то каждый поток обладает уникальным ThreadId


procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(IntToHex(GetCurrentThreadId, 8)); // Id осн.код.потока процесса

Test := TTest.Create(True);
ShowMessage(IntToHex(Test.ThreadId, 8)); // Id доп.код.потока процесса
Test.Resume;
end;

запусти приложение автономно (без отладки под Делфи)

теперь сравни полученные Id"ы с "показаниями" диспетчера задач.

Id осн.потока совпадет с одним из двух Id в диспетчере.

Если Id другого потока в диспетчере будет отличаться от Test.ThreadId, то, вероятно, это один из код.потоков, неявно стартованных ADO-механизмом. Почему он не завершается - этио уже другой вопрос.


nikulin   (2003-01-22 10:04:00) [6]

Так это же не изменило ситуации. Так же два потока осталось.


Digitman   (2003-01-22 09:59:00) [7]

type
TTest = class(TThread)
public
constructor Create(CreateSuspended: Boolean);
destructor Destroy; override;
private
{ Private declarations }
FADOCn: TADOConnection;
FADODataSet: TADODataSet;
procedure DoMsgBox; // !!!

protected
procedure Execute; override;
end;
....

constructor TTest.Create(CreateSuspended: Boolean);
begin
inherited Create(True); // !!!
Priority := tpNormal;
FreeOnTerminate := True;

FADOCn := TADOConnection.Create(nil);
FADOCn.ConnectionString := ConnectString;
FADOCn.Open;

FADODataSet := TADODataSet.Create(nil);
if CreateSuspended then // !!!
Resume; // !!!
end;

procedure TTest.DoMsgBox;
begin
MessageBox(0,"","",0); // !!!
end;

procedure TTest.Execute;
begin
try // !!!!!
FADOCn.Execute("select null");
// MessageBox(0,"","",0); // ????
Synchronize(DoMsgBox); // !!!!!
except // !!!!
// no exceptions must be raised/re-raised here !!!
end;
end;


Наверх

Титульная страница Поиск, карта сайта Написать письмо