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

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

Дополнительный поток и Exception в главном. Что будет?


Страницы:   1 2 3 4 5 6 7

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 потоко будет.

А я терерь переделаю:
<След пост>


Страницы:   1 2 3 4 5 6 7

Наверх

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