![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Дополнительный поток и Exception в главном. Что будет?
Kolan © (2006-10-15 22:43:00)Здравствуйте,
В программе есть доп поток. Что будет с доп. потоком если в гл. потоке произойдетException?
Kolan (2006-10-16 22:36:00) [1]Вообщем тема закрыта успешно. Всех благодарю, особенно Ketmar и Leonid Troyanovsky за вправление мозгов :)
Kolan (2006-10-16 21:51:00) [2]Аааа это из-за интерфейса, а я уже странно смеяться стал.
Из за исключения Package = nil. А это что приведет к AV вот тут?:
Package: IPackage
Kolan (2006-10-16 21:41:00) [3]Убейте меня пожалуйста. Теперь AV и тоже только при возникновении исключения.
Итак получив пакет я передаю его на обработку при помощи окна(AllocateHWND). В обработке возникает исключение,
Тут исключение:
FPackageRecieveEvent(Self, FPackageManager.ParseRecievedPackage(MyPackage));
Но, FPackageRecieveEvent вызывается:
procedure TMainForm.PackageRecieveEvent(Sender: TObject; Package: IPackage);
begin
ShowMessage('PackageRecieved');
end;
Окно показывается, нажимаю ОК - получаю AV.
Если исключения нет, то все нормально :)...
Уффф, благодарю за помощь. Чуть-чуть осталос, наверно :)
Kolan (2006-10-16 21:33:00) [4]
> Leonid Troyanovsky © (16.10.06 21:31) [128]
>
>
Ааа вот как надо, а я генофонд глянул и не че там не понял :) С AllocateHWND ИМХО приятнее тем более для этого оно и нужно :)
Leonid Troyanovsky (2006-10-16 21:31:00) [5]
> Kolan © (16.10.06 21:08) [122]
> Создавай потомка TForm.
type
TFormX = class (TForm)
public
constructor Create(AOwner: TComponent); override;
..
end;
constructor TFormX.Create;
begin
CreateNew(AOwner);
end;
--
Regards, LVT.
Kolan (2006-10-16 21:28:00) [6]:) Получилось, вроде. Правдо AV, шас поотлаживаю :)
Kolan (2006-10-16 21:20:00) [7]Вроде наваял с AllocateHwnd. Только незнаю как ссылку на объект в сообщении передать:
http://www.delphimaster.ru/cgi-bin/forum.pl?id=1161018380&n=18
Kolan (2006-10-16 21:18:00) [8]
> Да и неплохо осознавать, делается ли нечто одноразовое,
> или вещь на каждый день.
На каждый день. Этот менеджер связи - вообще универсальная штука. Я его вставляю во все проекты...
Leonid Troyanovsky (2006-10-16 21:15:00) [9]
> Kolan © (16.10.06 21:02) [121]
> > Сделай компонент, который
> А так как я предлагаю нельзя?
Можно, наверное.
Но, для того, чтобы делать нечто обобщающее, скажем,
аналог TDataSource как промежуточной абстракции
между слоями, представлениями и т.п., нужно наработать
некий материал, пищу для ума, дабы понять, что полезно,
а что лишнее.
Да и неплохо осознавать, делается ли нечто одноразовое,
или вещь на каждый день.
--
Regards, LVT.
Kolan (2006-10-16 21:11:00) [10]
> AllocateHwnd
О вроде то что надо.. Шас испробую.
Kolan (2006-10-16 21:08:00) [11]Создавай потомка TForm.
Ну, а я че делаю...
TSynchronizationForm = class(TForm)
public
procedure SXPackageReady(var Msg: TMessage); message SX_PACKAGEREADY;
end;
> Или, если нужно окно (невидимое), а не форма - AllocateHwnd.
Посмотрю.
Leonid Troyanovsky (2006-10-16 21:02:00) [12]
> Kolan © (16.10.06 20:46) [118]
> получаю resourse TSynchronizationForm not found. Как избавится?
Создавай потомка TForm.
Или, если нужно окно (невидимое), а не форма - AllocateHwnd.
--
Regards, LVT.
Kolan (2006-10-16 21:02:00) [13]
> Сделай компонент, который
А так как я предлагаю нельзя?
Leonid Troyanovsky (2006-10-16 20:58:00) [14]
> Kolan © (16.10.06 20:44) [117]
> А обработанное должно быть в TConnectionManager, а от Формы
> до него ого го см[106].
Ну, я так далеко не заглядывал :)
Сделай компонент, который, с одной стороны, будет лежать
на форме (и знать, как с ней взаимодействовать), а, с другой
стороны - создаст поток и тоже будет с ним взаимодействовать.
Если хочется, то можно снабдить компонент окном, на манер TTimer,
в которое и будет осуществляться PostMessage.
--
Regards, LVT.
Kolan (2006-10-16 20:46:00) [15]В жизни не создавал форм динамически, при
FSynchronizationForm := TSynchronizationForm.Create(nil);
получаю resourse TSynchronizationForm not found. Как избавится?
Kolan (2006-10-16 20:44:00) [16]
> Если не нужна синхронизация (обработки пакета),
> то поток может распределить блок нужного размера путем GetMem,
>
> заполнить его данными и отправить его адрес (размер) путем
> Post(Thread)Message главному потоку в форме WM_USER+x.
> Главный же поток, по окончании обработки, удалит блок.
Дааа, может Можно и не через GetMem, Но сообщение прийдет в форму.
А обработанное должно быть в TConnectionManager, а от Формы до него ого го см[106]. Что бы это сотворить надо предавать хендл формы во все эти классы.
И еще форма узнает о том что существует какой-то поток, какие-то байты нафиг её это надо, её дело нажатия на кнопочки обработать...
Leonid Troyanovsky (2006-10-16 20:39:00) [17]
> Kolan © (16.10.06 20:01) [111]
> Но в денном случае, опираясь на ваш код. В
> Synchronize(ShowResult); мне надо лишь отправить пакет дальше.
> .. и Тут же вернуться. Те никаких исключений в потоке не
Если не нужна синхронизация (обработки пакета),
то поток может распределить блок нужного размера путем GetMem,
заполнить его данными и отправить его адрес (размер) путем
Post(Thread)Message главному потоку в форме WM_USER+x.
Главный же поток, по окончании обработки, удалит блок.
Можно и без сообщений, моделируя очередь посредством TThreadList.
Т.е., рабочий поток заполняет его адресами блоков, а главный поток
в Application.OnIdle его обрабатывает.
--
Regards, LVT.
Kolan (2006-10-16 20:32:00) [18]Как правильно это сделать(Подчеркнутое)?
Kolan (2006-10-16 20:32:00) [19]Делаю форму:
TSynchronizationForm = class(TForm)
public
procedure SXPackageReady(var Msg: TMessage); message SX_PACKAGEREADY;
end;
Она - поле класса:
TConnectionManager = class
private
***
FSynchronizationForm: TSynchronizationForm;
FPackage: TByteArray;
При получении пакета:
procedure TConnectionManager.PackageReceivedEvent(Sender: TObject;
Package: array of Byte);
begin
SavePackage(Package);
PostMessage(FSynchronizationForm.Handle, SX_PACKAGEREADY,
Integer(Pointer(Self)), 0);
end;
При получении:
procedure TSynchronizationForm.SXPackageReady(var Msg: TMessage);
begin
(Msg.WParam as TConnectionManager).SendPackage;
end;
Вотэто идея. Проверит не могу, так как не могу правильно сохранить указатель на TConnectionManager(в смысле на его экземпляр). А затем вызвать функцию..
Процедура сохранения пакета:
procedure TConnectionManager.SavePackage(Package: array of Byte);
begin
Move(Package, FPackage, SizeOf(Package));
end;
Kolan (2006-10-16 20:10:00) [20]Вот короче этот злашастный менеджер целиком:
TConnectionManager = class
private
FCommPort: TAnisochronousComm;
FCommReadThread: TAnisochronousCommReadThread;
FPackageComposer: TPackageComposer;
FPackageExtractor: TPackageExtractor;
FConnectionManagerPackageReceivedEvent:
TConnectionManagerPackageReceivedEvent;
protected
{Events}
procedure CommReadEvent(Sender: TObject;
ReadBytes: array of Byte);
procedure SendPackageReadyEvent(Sender: TObject;
Package: array of Byte);
procedure PackageReceivedEvent(Sender: TObject;
Package: array of Byte);
public
constructor Create;
destructor Destroy; override;
procedure SendPackage(Package: array of Byte);
property ConnectionManagerPackageReceivedEvent:
TConnectionManagerPackageReceivedEvent read
FConnectionManagerPackageReceivedEvent write
FConnectionManagerPackageReceivedEvent;
end;
procedure TConnectionManager.CommReadEvent(Sender: TObject;
ReadBytes: array of Byte);
begin
FPackageExtractor.AddArray(ReadBytes);
end;
constructor TConnectionManager.Create;
begin
inherited Create;
FCommPort := TAnisochronousComm.Create;
FCommPort.Open;
FCommReadThread := TAnisochronousCommReadThread.Create(FCommPort);
FCommReadThread.CommReadEvent := CommReadEvent;
FPackageComposer := TPackageComposer.Create(StartByte, EndByte, LastByte);
FPackageComposer.SendPackageReadyEvent := SendPackageReadyEvent;
FPackageExtractor := TPackageExtractor.Create(StartByte, EndByte);
FPackageExtractor.PackageReceivedEvent := PackageReceivedEvent;
end;
destructor TConnectionManager.Destroy;
begin
FCommPort.Free;
FCommReadThread.Terminate;
FCommReadThread.Resume;
FPackageComposer.Free;
FPackageExtractor.Terminate;
FPackageExtractor.Resume;
Sleep(10);
inherited Destroy;
end;
procedure TConnectionManager.PackageReceivedEvent(Sender: TObject;
Package: array of Byte);
begin
if Assigned(FConnectionManagerPackageReceivedEvent) then
FConnectionManagerPackageReceivedEvent(Self, Package);
end;
procedure TConnectionManager.SendPackage(Package: array of Byte);
begin
FPackageComposer.AddArray(Package);
end;
procedure TConnectionManager.SendPackageReadyEvent(Sender: TObject;
Package: array of Byte);
begin
//
LogManager.WriteString('Written to Com');
LogManager.WriteByteArray(Package);
//
FCommPort.Write(Package, Length(Package));
end;
Те получив пакет я вызываю событие,FConnectionManagerPackageReceivedEvent
Там обрабатываю итд итп те в итоге все в Synchronize потоко будет.
А я терерь переделаю:
<След пост>