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?


Ketmar   (2006-10-15 23:51:00) [101]

что-то вы, барин, намудрили. может, перепроектировать, пока не поздно?


Kolan   (2006-10-15 23:48:00) [102]


> MessageDlg(EPackageWrongLength.ClassName, mtError, [mbOK],
>  0);

Показать сообщение - не цель. И вообще тут искл должно только возникнуть...

try
Synchronize(SendPackage);
except
on E: Exception do
begin
  Terminated := true
  // Или какая там реакция должна быть на исключение?
  // Если надо, то:  if (E is EPackageWrongLength) then
end;
end;


Потоку наплевать что там делается дальше он нашел пакет, сделал SendPackage и все занимается дальше своими делами...

PS
 Выходит вся обработка у меня в Synchronize находится - это плохо надо менять...
Но и сообщения неподходят или их надо применить по другому. Что же делать?

Дальше TConnectionManagerничего не должно пойти, он должен сам справится с обработкой пакета....


Ketmar   (2006-10-15 23:45:00) [103]

>[28] Kolan(c) 15-Oct-2006, 23:41
>Что делать? Еще варианты отреагировать есть? Без формы же
>с сообщениями не поработаешь?
поработаешь. завести ещё один поток. у потока тоже есть очередь сообщений. %-)


Percent   (2006-10-15 23:43:00) [104]

if Length(Package) < 13 then
  raise EPackageWrongLength.Create(EPackageWrongLength.ClassName);


Заменить на:

if Length(Package) < 13 then
begin
 MessageDlg(EPackageWrongLength.ClassName, mtError, [mbOK], 0);
 raise EPackageWrongLength.Create(EPackageWrongLength.ClassName);
end;

Synchronize(SendPackage);

Заменить на:

try
 Synchronize(SendPackage);
except
 on E: Exception do
 begin
   Terminated := true
   // Или какая там реакция должна быть на исключение?
   // Если надо, то:  if (E is EPackageWrongLength) then
 end;
end;


Kolan   (2006-10-15 23:41:00) [105]


> Блин, так для этого мне нужен хендл своего окна, да?

Да. PostMessage(FFormHandle, SX_PACKAGEREADY, 0, 0);

А чтобы его обработать в форме написать:
procedure SXPackageReady(var Msg: TMessage); message SX_PACKAGEREADY;

Выходит. It is unacceptable.

По двум причинам:
1. Чтобы передать Хендл в конструктор класса TConnectionManager(пост [22]). Придется передавть его еще много где.

2. Аналогично с реакцией на сообщение. И вообще у меня форма и знать не знает о всем этом безобразии..

Что делать? Еще варианты отреагировать есть? Без формы же с сообщениями не поработаешь?


Ketmar   (2006-10-15 23:37:00) [106]

>[26] Kolan(c) 15-Oct-2006, 23:31
>Блин, так для этого мне нужен хендл своего окна, да?
ну так он есть. свойство Handle у TForm. и обработчики сообщений. тебя что, тоже посылать на F1? %-)


Kolan   (2006-10-15 23:31:00) [107]


> а подумать? например, послать (post) самому себе сообщение
> "работай, гадюка!"

Опять сообщения...  Ими и пользовался... Потом переделал через события получилось аккуратнее, но не правильно видимо...

Блин, так для этого мне нужен хендл своего окна, да?


Kolan   (2006-10-15 23:26:00) [108]


> Весь код выполняется в главном потоке, начитался Архангельского?

Не его не читал ни разу, даже в руках не держал. Обработку в этом потоке сделать нельзя. Он занят...


Ketmar   (2006-10-15 23:26:00) [109]

>[22] Kolan(c) 15-Oct-2006, 23:24
>А как?
а подумать? например, послать (post) самому себе сообщение "работай, гадюка!"


Ketmar   (2006-10-15 23:25:00) [110]

фтыкать в [15], [17], [18], [19]. думать.


Kolan   (2006-10-15 23:24:00) [111]


> Ketmar ©   (15.10.06 23:17) [17]

Я понял основную мысль - это хорошо :)
Так Сам SendPackage трогать не буду

В конце SendPackageвыполняется:
FPackageReceivedEvent(Self, Answer);

И попадаю суда:

procedure TConnectionManager.PackageReceivedEvent(Sender: TObject;
 Package: array of Byte);
begin
 if Assigned(FConnectionManagerPackageReceivedEvent) then
   FConnectionManagerPackageReceivedEvent(Self, Package);  
end;


Допустим я копирую массив в поле класса. И заканчиваю PackageReceivedEvent, а следовательно и SendPackage. Те все "ОК".

Но ведь нужно вызвать FConnectionManagerPackageReceivedEvent(Self, Package);

А как?


Percent   (2006-10-15 23:19:00) [112]

исключение исключение

"Я никогда не повторяюсь... не повторяюсь..." (С)

:о)


Ketmar   (2006-10-15 23:17:00) [113]

резюмируя: Synchronize() -- это очень быстро, и обязательнодолжно завершиться безо всяких исключений. надо обработку -- сохраняй где-то данные, возвращайся из SendPackage(), и обрабатывай уже потом. а то у тебя не параллельная работа получается, а непонятно что.


Anatoly Podgoretsky   (2006-10-15 23:17:00) [114]

Весь код выполняется в главном потоке, начитался Архангельского?


Percent   (2006-10-15 23:17:00) [115]

Kolan ©

Наводящий вопрос: Кто отображает окошко с сообщением?
Подсказка: Application
Второй (повторный) наводящий вопрос: Куда "вывалится" исключение исключение?
Вторая подсказка: В поток.
Третий вопрос: Как обрабатываются исключения в потоках?
Третья подсказка: Читайте справку...


Kolan   (2006-10-15 23:17:00) [116]

В итоге
 SendPackage приведет к возникновению исключения.

Вот как бы полный(почти) путь, если надо:

В SendPackage:
 //***
 FPackageReceivedEvent(Self, Answer);
 //**

Далее

procedure TDeviceManager.PackageReceivedEvent(Sender: TObject;
 Package: array of Byte);
/**
begin
//**
 if Assigned(FPackageRecieveEvent) then
   FPackageRecieveEvent(Self, FPackageManager.ParseRecievedPackage(MyPackage));
/**
end;


Далее
Result := FRecievePackageBuilder.ParseRecievedPackage(Package);

Далее:

function TRecievePackageBuilder.ParseRecievedPackage(
 Package: TByteArray): TPackage;
var
 Header, UserData: TByteArray;
begin
 Result := TPackage.Create;
 try
    SeparateHeaderAndUserDtaArrays(Package, Header, UserData);
   {FillHeader(Result.Header, Header);
   FillUserData(Result.Data, UserData);
   CheckHeaderCS(Result.Header, Header);
   CheckUserDataCS(Result.Data, UserData);}
 except
   Result.Free;
   raise;
 end;
end;


Далее:
CheckPackageLength(Package);

Далее
procedure TRecievePackageBuilder.CheckPackageLength(Package: array of Byte);
begin
 if Length(Package) < 13 then
   raise EPackageWrongLength.Create(EPackageWrongLength.ClassName);
end;


Ketmar   (2006-10-15 23:14:00) [117]

т.е. exception вываливается в вызове Synchronize()? так чего тебе боле? натурально, будут глюки. потому что "синхрониз" должен возвернуться. а у тебя он куда-то в обработчик исключений улетает в процессе. а что в обработчике -- ведомо лишь Аллаху... если ведомо. %-)

зыж это телепатор, проблема пока так и не ясна.


Percent   (2006-10-15 23:14:00) [118]

Вот и отложилось у меняисключения и потоки - не совместимы

Зубные камни удаляет стоматолог.


Percent   (2006-10-15 23:13:00) [119]

Synchronize(SendPackage);

И до куда, в таком случае, дойдет исключение?


Kolan   (2006-10-15 23:13:00) [120]

Лирическое отступление:
 Когдато я разобрался с исключениями и использовал их в одном модуле. Потом поняв что мне необходим доп. поток я переделал проект и использовал в потоке модуль с исключениями. В результате при возникновении исключения получалось: "Программа выполнила .. и будет закрыта".
Вот и отложилось у меня исключения и потоки - не совместимы. А так как важные проекты все с доп потоками, то и исключения я не использую вообще. Вместо этого Enumeration...
Вот решил что был тогда неправ и исключения надо пользовать и опять..... Хоть и ситуация другая.

Может всетаки ну их нафик этои исключения?


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

Наверх

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