![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Дополнительный поток и Exception в главном. Что будет?
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...
Вот решил что был тогда неправ и исключения надо пользовать и опять..... Хоть и ситуация другая.
Может всетаки ну их нафик этои исключения?