Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.11.26;
Скачать: CL | DM;

Вниз

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

 
Kolan ©   (2006-10-15 22:43) [0]

Здравствуйте,
 В программе есть доп поток. Что будет с доп. потоком если в гл. потоке произойдет Exception?


 
guav ©   (2006-10-15 22:47) [1]

> Что будет с доп. потоком если в гл. потоке произойдет Exception?

Ничего. Дальше полетит.


 
Ketmar ©   (2006-10-15 22:47) [2]

работать себе будет. пока программа не грохнется окончательно.


 
Leonid Troyanovsky ©   (2006-10-15 22:47) [3]


> Kolan ©   (15.10.06 22:43)  

>  В программе есть доп поток. Что будет с доп. потоком если
> в гл. потоке произойдет Exception?


Зависит от плотности связи вторичного и первичного.

--
Regards, LVT.


 
Ketmar ©   (2006-10-15 22:51) [4]

>[3] Leonid Troyanovsky(c) 15-Oct-2006, 22:47
>Зависит от плотности связи вторичного и первичного.
а, ну да. натурально. если независим -- будет работать. если чего от главного хочет... ну, не повезло тогда доппотоку. %-)


 
Kolan ©   (2006-10-15 22:54) [5]

Система такая полученные данные обрабатываются в доп потоке. Как только обработка закончена он засыпает. Далее обработанные данные отправляются в гл. поток. В гл потоке я проверяю корректность 1 что делаю проверяю длину:

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


Так вот если длинна не верная, то:
Доходит до raise, но окно сообщением не появляется. Почему?
Зато при закрытии программы(точнее при удалении потока) выдает: "Неверный дескриптор" ...

Если Exception закаментить то все ок...


 
Percent   (2006-10-15 22:55) [6]

Далее обработанные данные отправляются в гл. поток.

Тема механизма передачи не озвучена...


 
Ketmar ©   (2006-10-15 22:55) [7]

"не верю!" (ц) минимальный код, демонстрирующий эту аномалию -- в студию.


 
Kolan ©   (2006-10-15 22:56) [8]

Synchronize(SendPackage);


 
Kolan ©   (2006-10-15 22:56) [9]


> "не верю!" (ц) минимальный код, демонстрирующий эту аномалию
> -- в студию.

Шас


 
guav ©   (2006-10-15 22:57) [10]

Does the flap of a butterfly’s wings in One Thread set off a tornado in Another Thread ?


 
Kolan ©   (2006-10-15 23:05) [11]

Общий смысл который я понял при дебеге:
поток(пишу прям здесь если не то, то буду выбирать из реального кода):
while not Terminated do
 begin
   if ReadIndex >= WriteIndex then
   begin

     Suspend;
     if Terminated then
     begin

       Break;
     end;
     Synchronize(SendPackage);
           if (ReadIndex <> WriteIndex ) then
             RearrangeBuffer;
  end;


1. Если нет Exceptiona:
 После Synchronize(SendPackage); показывается окно что типа все нормально(я же ошибку закометил). Нажав на "ОК" попадаю на точку: while not Terminated do.

2. С Exception После Synchronize(SendPackage); ничего(вообще) на while not Terminated do уже не попадает.

Закрываю - "Неверный дескриптор".


 
Kolan ©   (2006-10-15 23:06) [12]


> Does the flap of a butterfly’s wings in One Thread set off
> a tornado in Another Thread ?
>

Something like this :)


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

Synchronize(SendPackage);

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


 
Kolan ©   (2006-10-15 23:13) [14]

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

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


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

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

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


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

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

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


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

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


 
Anatoly Podgoretsky ©   (2006-10-15 23:17) [18]

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


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

Kolan ©

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


 
Kolan ©   (2006-10-15 23:17) [20]

В итоге
 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;


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

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

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

:о)


 
Kolan ©   (2006-10-15 23:24) [22]


> 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);

А как?


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

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


 
Kolan ©   (2006-10-15 23:26) [24]


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

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


 
Ketmar ©   (2006-10-15 23:26) [25]

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


 
Kolan ©   (2006-10-15 23:31) [26]


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

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

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


 
Ketmar ©   (2006-10-15 23:37) [27]

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


 
Kolan ©   (2006-10-15 23:41) [28]


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

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

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

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

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

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

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


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

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;


 
Ketmar ©   (2006-10-15 23:45) [30]

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


 
Kolan ©   (2006-10-15 23:48) [31]


> 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:51) [32]

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


 
Percent   (2006-10-15 23:52) [33]

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

Тогда зачем генерить исключение?


 
Kolan ©   (2006-10-15 23:53) [34]


> поработаешь. завести ещё один поток. у потока тоже есть
> очередь сообщений. %-)

Только об этом подумал, тогда у меня вообще вся обработка будет в потоке, так?

Те завожу поток "Обработки". Когда происходит событие
procedure TConnectionManager.PackageReceivedEvent(Sender: TObject;
Package: array of Byte);

Я сохраняю пакетик и посылаю потоку сообщение, он берет пакет и делает свои дела.
Вроде нормально?
+ синхронизация.


 
Ketmar ©   (2006-10-15 23:54) [35]

вроде того.


 
Leonid Troyanovsky ©   (2006-10-15 23:56) [36]


> Kolan ©   (15.10.06 23:53) [34]

> Те завожу поток "Обработки". Когда происходит событие


А зачем заводить?
Первичный поток вполне справится с их обработкой.
Бо, в большинстве это - показ исключения.

--
Regards, LVT.


 
Kolan ©   (2006-10-15 23:56) [37]


> Тогда зачем генерить исключение?

Я неправильно выразился. Не с обработкой, а с прекращением выполнения SendPackage и отправкой сообщения о том что есть что обрабатывать


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

Да тут мудрить вроде нечего. Перепроектирую наверно но не много..

Этот TConnectionManager имеет 1 метод - послать и 1 событие-пришли данные. Оч. удобно, я его много где использовал...


 
Percent   (2006-10-15 23:58) [38]

в большинстве это - показ исключения.

Ему и показывать-то ничего не надо, оказывается... "Показать сообщение - не цель" (С) Kolan


 
Kolan ©   (2006-10-16 00:02) [39]



> А зачем заводить?
> Первичный поток вполне справится с их обработкой.


> Бо, в большинстве это - показ исключения.

Ну и я так думал. Сдеал серию событий. И получилось что в итоге у меня в Synchronize(SendPackage); все нчиная от обработки пакета, до вычисления данных и рисования на чарте. Гы, и работает :) Если без исключений.

Так а как сделать в главном?


> вроде того.

Тогда в итоге в этом потоке "обработки" я все обработаю и через Synchronize вызову событие, которое приведет к рисованию на чарте. Это ничего?


 
Leonid Troyanovsky ©   (2006-10-16 00:03) [40]


> Percent   (15.10.06 23:58) [38]


Зря ты не регистрируешься.

Ну, ладно, иду спать.

--
Regards, LVT.



Страницы: 1 2 3 4 вся ветка

Текущий архив: 2006.11.26;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.043 c
11-1139299870
ElDev
2006-02-07 11:11
2006.11.26
Ребята помогите, нужен MHMonthCalendar!


2-1162871719
Dimon20
2006-11-07 06:55
2006.11.26
Поиск по таблице


2-1162845983
Gunek
2006-11-06 23:46
2006.11.26
Как к тексту запроса добавить переменную?


15-1162961226
vajo
2006-11-08 07:47
2006.11.26
В Японии создан 512-ядерный процессор


2-1162916584
qbegin
2006-11-07 19:23
2006.11.26
case