Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2006.11.26;
Скачать: [xml.tar.bz2];

Вниз

Дополнительный поток и 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.


 
Kolan ©   (2006-10-16 00:03) [41]


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

Да не цель, я по исключению что-то сделаю, отреагирую так сказать.
Сейчас показываю для отладки.


 
Leonid Troyanovsky ©   (2006-10-16 00:07) [42]


> Kolan ©   (16.10.06 00:03) [41]

> Сейчас показываю для отладки.


Показывать же надо через Synchronize.

--
Regards, LVT.


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


> Показывать же надо через Synchronize.

Ни че не пойму. В потоке исключения не возникают. Они возникают в методе, вызванном через Synchronize. Те так как вы говорите, а это приводит к [17]


 
Ketmar ©   (2006-10-16 00:12) [44]

>[43] Kolan(c) 16-Oct-2006, 00:10
ну почитай ты генофонд, а? %-)


 
Leonid Troyanovsky ©   (2006-10-16 00:17) [45]


> Kolan ©   (16.10.06 00:10) [43]

> > Показывать же надо через Synchronize.

> Ни че не пойму. В потоке исключения не возникают. Они возникают
> в методе, вызванном через Synchronize.

Ну, если они не обрабатываются в том самом методе,
то должны быть обработаны в потоке, вызвавшем Synchronize.
Однако, если в этом потоке возникла нужда в к.л. показе, то оный
должен быть, опять же, в Synchronize (но, видимо, в ином).

--
Regards, LVT.


 
Kolan ©   (2006-10-16 00:19) [46]


> ну почитай ты генофонд, а? %-)

Генофонд ниасилю. А вот Тейктеру и Пачеко перечитал про Synchroonize. Ну как бы ... а что я должен был понять?


 
Ketmar ©   (2006-10-16 00:20) [47]

>[46] Kolan(c) 16-Oct-2006, 00:19
>Synchroonize. Ну как бы ... а что я должен был понять?
а я откуда знаю? %-)


 
Kolan ©   (2006-10-16 00:23) [48]


> Ну, если они не обрабатываются в том самом методе,
> то должны быть обработаны в потоке, вызвавшем Synchronize.
>

Так усвоил.

Однако, если в этом потоке возникла нужда в к.л. показе, то оный
должен быть, опять же, в Synchronize (но, видимо, в ином).

Тоже дошло.


> Ну, если они не обрабатываются в том самом методе,


Вопрос: А если обрабатываются?

Result := TPackage.Create;
 try
   SeparateHeaderAndUserDtaArrays(Package, Header, UserData);

 except
   Result.Free;
 end;


 
Kolan ©   (2006-10-16 00:25) [49]


> ну почитай ты генофонд, а? %-)

Читать могу хоть сто раз. Пока не пойму на что обратить внимание не разберусь :(.

PS
 Я знаю что я тупой. :)


 
Ketmar ©   (2006-10-16 00:31) [50]

>[49] Kolan(c) 16-Oct-2006, 00:25
>Читать могу хоть сто раз. Пока не пойму на что обратить
>внимание не разберусь :(.
тогда заучи. чтобы даже во сне отбарабанивал. озарение само придёт. %-)

зыж это я засыпаю уже. вторые сутки. или третьи? оттого и сумбур. %-)


 
Leonid Troyanovsky ©   (2006-10-16 00:32) [51]


> Kolan ©   (16.10.06 00:23) [48]

> Вопрос: А если обрабатываются?


Без re-raise?
Тогда, как обычно, как будто их вовсе нет.

--
Regards, LVT.

PS
http://groups.google.com/group/fido7.ru.delphi/msg/d9a27ed6dbccaf7f


 
Kolan ©   (2006-10-16 00:37) [52]


> оттого и сумбур. %-)

Ну тебя. Ну не могу я понять...

Почему после Synchronize(SendPackage); доп поток чего-то ждет?
Вот передал он скрытому окну сообщение CM_EXECPROC и свой метод. И сё чего еще ждать?

Почему если в SendPackage исключение - обработанное, то с доп потоком что-то случается.


 
Ketmar ©   (2006-10-16 00:40) [53]

>[52] Kolan(c) 16-Oct-2006, 00:37
ой, ну тебя. если завтра проснусь -- проверю и попробую что-то внятное сформулировать. коли до того кто не расскажет. и ежели я не забуду да не обломлюсь. %-)


 
Kolan ©   (2006-10-16 00:40) [54]


> Тогда, как обычно, как будто их вовсе нет.

Да, понятно. Окна нет будет.
Вот, с этим я разобрался.
Те. при ре райзе обработка должна быть в доп потоке. Если его нет, то в главном все заканчиватся. Так?
Но почему "Неверый дискриптор" при закрытии? Ошибка в 17 строке что-ли?


 
Kolan ©   (2006-10-16 00:44) [55]


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

Чем больше думаю ... Все таки не может быть, что доп поток ждет пока закончится метод в Synchronize. По косвенной причине точно. Иногда доп поток работает оч. интенсивно, если бы он ждал данные испортились бы...


 
Kolan ©   (2006-10-16 00:45) [56]

Ладно, завтра тему еще подниму. Так как не разобрался я нифига, еще больше запутался.


 
Ketmar ©   (2006-10-16 00:46) [57]

цитата из справки: "Execution of the thread current is suspended while Method executes in the main thread."


 
Leonid Troyanovsky ©   (2006-10-16 00:51) [58]


> Kolan ©   (16.10.06 00:44) [55]

> Чем больше думаю ... Все таки не может быть, что доп поток
> ждет пока закончится метод в Synchronize.

На то он и Synchronize, чтоб ждать, пока все не кончится
в первичном.

--
Regards, LVT.


 
Германн ©   (2006-10-16 00:52) [59]

Всё прочесть не осилил.
Но помимо одного "геморроя" (работа с внешним устройством по СОМ-порту в доппотоке), добавлен ещё и второй - "проблемы с исключениями в доппотоках".
P.S. Из анекдота всем известного - "Доктор, я буду жить? Будешь, но х#%во!"


 
Kolan ©   (2006-10-16 00:53) [60]

Так... точно есть...

А удаляю поток так:
 destructor TConnectionManager.Destroy;
begin
 FCommPort.Free;
 FCommReadThread.Terminate;
 FCommReadThread.Resume;
 FPackageComposer.Free;
 FPackageExtractor.Terminate;
 FPackageExtractor.Resume;

 Sleep(10);
inherited Destroy;
end;


При FCommReadThread.Resume; и получается "Неверный дескриптор". Вот наверно почему.

Если удаляю не так, то я не виноват :) как-то тут обсуждал как удалить спящий, не спящий поток.. Получилось так.

Ладно надо думать как переделать.

PS
 Тема не закрыта..


 
Kolan ©   (2006-10-16 00:55) [61]


> (работа с внешним устройством по СОМ-порту в доппотоке)

Это пока не трогаем - это тоже есть,  это не ток поток, и это надо в отдельную конференцию....

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


 
Percent   (2006-10-16 00:57) [62]

Но почему "Неверый дискриптор" при закрытии?

При возникновении исключения в потоке, если это исключение не перехватывается программным кодом потока, происходит "аварийное" завершение потока, и поток удаляется средствами ОС как "преждевременно почивший". То есть, поток - это сущность ОС, и реальное управление им осуществляет ОС. При завершении приложения, производится обращение к потоку, уже удаленному средствами ОС. А так как потока уже реально не существует, то и дескриптор его - неверный. Типа как-то вот так. Читай внимательно про обработку исключений в потоках. То есть, я хотел сказать, что выпускать исключение из потока не следует...


 
Kolan ©   (2006-10-16 00:58) [63]


> На то он и Synchronize, чтоб ждать, пока все не кончится
> в первичном.

Вот она истина, а мне нужен такой же Synchronize(тока без крыльев), но чтобы не ждал. Те это PostMessage, но он не подходит. Очень не хочется так делать. Некрасиво если форма знает о каком-то порте... Я считаю, что она не должна.


 
Leonid Troyanovsky ©   (2006-10-16 00:58) [64]


> Kolan ©   (16.10.06 00:53) [60]

> Если удаляю не так, то я не виноват :) как-то тут обсуждал
> как удалить спящий, не спящий поток.. Получилось так.


А с чего-то он вдруг попал в suspend?
С этим, дейс-но, надо разобраться, вне зависимости от
прошлых обсуждений.

--
Regards, LVT.


 
Percent   (2006-10-16 00:59) [65]

А удаляю поток так:
destructor TConnectionManager.Destroy;
begin
FCommPort.Free;
FCommReadThread.Terminate;
FCommReadThread.Resume;
FPackageComposer.Free;
FPackageExtractor.Terminate;
FPackageExtractor.Resume;
Sleep(10);
inherited Destroy;
end;


А где здесь удаление потока?


 
Германн ©   (2006-10-16 01:01) [66]


> Kolan ©   (16.10.06 00:55) [61]
>
>
> > (работа с внешним устройством по СОМ-порту в доппотоке)
>
> Это пока не трогаем - это тоже есть,  это не ток поток,
> и это надо в отдельную конференцию....
>
> Кстати пока с этим проблем не возникало, те получить данные
> из порта - проблем нет...
>

Тут главное слово пока! Возможно даже, что у тебя никогда проблемм и не будет, а будут они у пользователей!


 
Kolan ©   (2006-10-16 01:03) [67]


> А с чего-то он вдруг попал в suspend?
> С этим, дейс-но, надо разобраться, вне зависимости от
> прошлых обсуждений.

Я его попросил. Общий смысл.
1. Прихдят данные. Надо выделить пакет(Начало и конец искать надо).
2. Но пакеты длинные и приходят частями.

Поэтому я завел поток(о нем мы и говорили все это время). Как только что-то пришло оно кладется в буффер потока и поток просыпается и начинает просматривать данные.
Если все вновь прибывшее просмотрел и пакет не нашел - засыпает. Если нашел Выдает его - это и есть Synchronize(SendPackage);.


 
Kolan ©   (2006-10-16 01:05) [68]


> Тут главное слово пока! Возможно даже, что у тебя никогда
> проблемм и не будет, а будут они у пользователей!

Тут бы с этим разобраться. Связь устраиватет. Вот будет неработатья тебя вспомню :).

> А где здесь удаление потока?

Угадай :) FreeOnTerminate := True;


 
Leonid Troyanovsky ©   (2006-10-16 01:06) [69]


> Percent   (16.10.06 00:57) [62]

> При возникновении исключения в потоке, если это исключение
> не перехватывается программным кодом потока, происходит
> "аварийное" завершение потока, и поток удаляется средствами

Начиная с D5+ обработка исключений во вторичном потоке изменилась.
Т.е., до того, необработанные исключения в потоке приводили
к завершению приложения (что и есть правильно).
Ну, а куда деваются исключения нынче надо посмотреть.
В понедельник, т.е., уже сегодня, наверное :)

--
Regards, LVT.


 
Kolan ©   (2006-10-16 01:06) [70]


> Возможно даже, что у тебя никогда проблемм и не будет, а
> будут они у пользователей!
>

А какие. Пусть у меня перед сном вообще моск прокиснет и я как Гоголь возьму и сотру эти модули, которые писал и доробатывал 1,5 года :)


 
Kolan ©   (2006-10-16 01:07) [71]


> Начиная с D5+ обработка исключений во вторичном потоке изменилась.
>  

Кстати делаю все на D2006


 
Percent   (2006-10-16 01:08) [72]

Угадай :) FreeOnTerminate := True;

Sleep(10); - типа, ожидание самоубийства потока?


 
Leonid Troyanovsky ©   (2006-10-16 01:11) [73]


> Kolan ©   (16.10.06 01:03) [67]

> Если все вновь прибывшее просмотрел и пакет не нашел - засыпает.


Дык, пусть спит на WaitFor..(Ex), instead suspend.

--
Regards, LVT.


 
Kolan ©   (2006-10-16 01:13) [74]


> Sleep(10); - типа, ожидание самоубийства потока?

Точно. Ну а как? Раньше просто делал Terminate и были утечки. Хоть потоки и удаляются при закрытии приложения, но все же...

PS
 Чувствую себя примерно так: Пошел к зубному на обычный осмотр, оказалось через 2 дня помру, потому что тут ППЦ тут жо..а, тут вообще лечению не поддается...


 
Kolan ©   (2006-10-16 01:15) [75]


> Дык, пусть спит на WaitFor..(Ex), instead suspend.

А это не аналог? Думал разницы нет.... что так что так...


 
Leonid Troyanovsky ©   (2006-10-16 01:21) [76]


> Kolan ©   (16.10.06 01:13) [74]

>  Хоть потоки и удаляются при закрытии приложения, но все


А может утечки были из-за того, с чем работал поток?
Т.е., не мог он нормально (при Terminated) завершиться?

--
Regards, LVT.


 
Kolan ©   (2006-10-16 01:25) [77]


> А может утечки были из-за того, с чем работал поток?
> Т.е., не мог он нормально (при Terminated) завершиться?
>

Утечки были потому, что деструктор потока не вызывался.

Ну если он спит (Не важно как Suspended или ждет Event) и Terminated := True , как же он(поток) его(Terminated) проверит - никак.... Вот я такое и навоял :)


 
Leonid Troyanovsky ©   (2006-10-16 01:26) [78]


> Kolan ©   (16.10.06 01:15) [75]

> А это не аналог? Думал разницы нет.... что так что так..


Не совсем. Т.е., Resume должен делать первичный поток.
А вывод из Wait.. - по освобождению ожидаемого.
Если это еще и Ex - то и, например, по получению QueueUserAPC.

--
Regards, LVT.


 
Rem ©   (2006-10-16 01:30) [79]

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

Да я уже давно, как бы... :-)

Ну, а куда деваются исключения нынче надо посмотреть.

function ThreadProc(Thread: TThread): Integer;
var
 FreeThread: Boolean;
begin
 try
   if not Thread.Terminated then
   try
     Thread.Execute;
   except
     Thread.FFatalException := AcquireExceptionObject;
   end;
 finally
   FreeThread := Thread.FFreeOnTerminate;
   Result := Thread.FReturnValue;
   Thread.FFinished := True;
   Thread.DoTerminate;
   if FreeThread then Thread.Free;
   EndThread(Result);
 end;
end;

(C) Delphi 6

Вот туда (FFatalException) они и "паркуются". То есть, это даже не ОС завершает поток, а он сам...


 
Германн ©   (2006-10-16 01:31) [80]


> Kolan ©   (16.10.06 01:06) [70]
>
>
> > Возможно даже, что у тебя никогда проблемм и не будет,
>  а
> > будут они у пользователей!
> >
>
> А какие. Пусть у меня перед сном вообще моск прокиснет и
> я как Гоголь возьму и сотру эти модули, которые писал и
> доробатывал 1,5 года :)
>

Ну вот давеча наблюдали всем техотделом такую ситуацию. В программе, где идёт работа с портом возникло исключение. Программа сдохла, но перезапустить её не было никакой возможности. Даже на CAD система не реагировала! :-)


 
Kolan ©   (2006-10-16 01:34) [81]


> Не совсем. Т.е., Resume должен делать первичный поток.

Даааа... а в справке тока: Pauses a running thread.
У меня поток сам себя усыпляет:

 while not Terminated do
 begin
   if ReadIndex >= WriteIndex then
   begin
     Suspend;
//****


> Если это еще и Ex - то и, например, по получению QueueUserAPC.


QueueUserAPC Да, это я еще...

Я понял что вместо Suspend надо сделать
 WaitForSingleObject(Event, INFINITE);  - не так? Нужен именно Ex? - С этой ф-цие не работал...  :(


 
Kolan ©   (2006-10-16 01:37) [82]


> В программе, где идёт работа с портом возникло исключение.

До сегодняшнего дня у меня небыло исключений. в окрестности порта. Ошибочки обрабатывал с пом. Enumeration.. Вот решил за исключения взяться.

А работа с портом в потоке - это из нета. А как еще чтобы не висло?


 
Leonid Troyanovsky ©   (2006-10-16 01:41) [83]


> Kolan ©   (16.10.06 01:34) [81]

> У меня поток сам себя усыпляет:


Усыпиться-то он может. А вот resume нужен извне.

>  WaitForSingleObject(Event, INFINITE);  - не так? Нужен
> именно Ex? - С этой ф-цие не работал...  :(

Ну, у молодых все еще спереди :)
Вкл., возможно, ReadFileEx & etc.

--
Regards, LVT.


 
Kolan ©   (2006-10-16 01:41) [84]

Да вот сюда я и попадаю со своим исключением.

{$IFDEF LINUX}
 if Thread.FSuspended then sem_wait(Thread.FCreateSuspendedSem);
{$ENDIF}
 try
   if not Thread.Terminated then
   try
     Thread.Execute;
   except
     Thread.FFatalException := AcquireExceptionObject;
   end;

Отсюда и неверный дискриптор...


 
Kolan ©   (2006-10-16 01:53) [85]


> А вот resume нужен извне.

Да это извне ессно.
При добавлении новых данных делается Resume. Все же тут разницы нет наверно. Что Resume что SetEvent...


> Ex

Надо посмотреть


> Да вот сюда я и попадаю со своим исключением.

Ни че не пойму с этими исключениями...
Если:
try
   SeparateHeaderAndUserDtaArrays(Package, Header, UserData);
 except
   Result.Free;
   //raise;
 end;

Это же исключение обработано? Так?
Так че оно в
except
    Thread.FFatalException := AcquireExceptionObject;

поподает?


 
Германн ©   (2006-10-16 01:59) [86]


> Kolan ©   (16.10.06 01:37) [82]
>
>
> > В программе, где идёт работа с портом возникло исключение.
>
>
> До сегодняшнего дня у меня небыло исключений. в окрестности
> порта. Ошибочки обрабатывал с пом. Enumeration.. Вот решил
> за исключения взяться.
>
> А работа с портом в потоке - это из нета. А как еще чтобы
> не висло?
>

Дык, исторически микросхема UART представляла максимум возможностей для асинхронной работы с ней. Драйверы СОМ-порта в Windows умеют использовать эти возможности.
Ну а в Дельфи оьрати внимание на параметр FILE_FLAG_OVERLAPPED и на


 
Kolan ©   (2006-10-16 08:30) [87]


> Ну а в Дельфи оьрати внимание на параметр FILE_FLAG_OVERLAPPED
> и на

Этим и пользуюсь. Те у меня асинхронная работа и в потоке :)


 
Сергей М. ©   (2006-10-16 08:48) [88]


> Kolan ©   (16.10.06 08:30) [87]


> у меня асинхронная работа и в потоке


И зачем там нужна асинхронность ?
У тебя что, доп.поток еще чем-то занимается, кроме как работой с портом ?


 
Rem ©   (2006-10-16 09:25) [89]

У меня поток сам себя усыпляет:

while not Terminated do
begin
  if ReadIndex >= WriteIndex then
  begin
    Suspend;


Очень трудно разобраться с приведенными фрагментами кода, и я не знаю, что такое ReadIndex и WriteIndex, однако, думаю, удобнее реализовать таким образом:

while not Terminated do
begin
 while not Terminated and (ReadIndex >= WriteIndex) do
   Sleep(0); // 10, 20 или другая цифра по условию задачи
 {...}
end;

То есть, усыплять поток не надо будет...


 
Kolan ©   (2006-10-16 10:16) [90]


> У тебя что, доп.поток еще чем-то занимается, кроме как работой
> с портом ?

Нет
> Очень трудно разобраться с приведенными фрагментами кода,
>  и я не знаю, что такое ReadIndex и WriteIndex, однако,
> думаю, удобнее реализовать таким образом:

У меня там циклический буффер. Соотв индек по которому пишу данные и индекс по которому читаю и ищу начало/конец пакета.

> Sleep(0);

Гы :) Было и такое решение. Ну а зачем? А если данные часами не прийдут? Че он будет молотить в пустую?


 
Percent   (2006-10-16 10:27) [91]

Че он будет молотить в пустую?

Предлагаешь выключить компьютер? :-)

Поставь Sleep(50), и не мучайся...


 
Сергей М. ©   (2006-10-16 10:30) [92]


> Kolan ©   (16.10.06 10:16) [90]
> Нет


Тогда зачем асинхронный режим задействован ?


 
Kolan ©   (2006-10-16 10:42) [93]


> Тогда зачем асинхронный режим задействован ?

ХЗ. Дела я все это по статье:
http://morgeyz.elayne.ru/comlpt.htm

В конце статьи:

Теперь, но ОЧЕНЬ кратко, залезем в еще большие дебри. Предположим, что протокол обмена с Вашим устройством, подключенным к последовательному порту, очень сложен (передаются большие и сложные структуры данных). При этом Ваша программа должна получать уже полностью принятую и проверенную информацию. Предположим так же, что Ваша программа занимается очень большими и сложными вычислениями и ей нет времени отвлекаться на обработку ввода/вывода. Да и сложность ее такова, что встраивание фонового ввода/вывода сделает ее трудно прослеживаемой и неустойчивой. Чувствуете, куда я клоню? Правильно, к выделению всех тонкостей ввода/вывода в отдельный поток. Возможно выделение и в отдельную задачу, но в этом случае мы не получим никакой выгоды, а накладные расходы на переключение задач гораздо больше, нежели на переключение потоков в одной задаче.

Прям про мою задачу :) Вот я и выделил...


 
Kolan ©   (2006-10-16 10:42) [94]


>
> Предлагаешь выключить компьютер? :-)
>
> Поставь Sleep(50), и не мучайся...
>

Все же усыплять - красивше :) У меня тогда душа спокойна :)...


 
Kolan ©   (2006-10-16 10:49) [95]


> Ни че не пойму с этими исключениями...

Как бы так и продолжаю не понимать :)

Думаю сделаю так:
 В еще одном потоке "обработки" завиду очередь пакетов. При получении пакета буду туда добавлять и будить его. Поток будет просыпаться выбирать пкеты и обрабатывать. Ну как?

Дальше обработав пакет(массив) он будет создавать объект пакет.
И отдавать на обработку гл потоку. Опять же как тут быть? Опять Synchronize(DoSmth)? Получится тоже самое... Только теперь другой поток будет ждать пока DoSmth не завершится..


 
Сергей М. ©   (2006-10-16 10:54) [96]


> Kolan ©   (16.10.06 10:42) [93]


Цитата из той же статьи:

Так как в потоке ввода/вывода, выполняющемся параллельно основному потоку программы, можно использовать асинхронный ввод/вывод, то достаточно просто реализуется возможность обработки большого количества портов

Твой доп.поток работает всего лишь с одним портом, а не с несколькими одновременно.

Чем в этом случае оправдан выбор асинхронного режима ?


 
Kolan ©   (2006-10-16 10:56) [97]


> Чем в этом случае оправдан выбор асинхронного режима ?

Смешно конечно звучит: Чтобы форма не висла... Работает пока и бог с ним. Тут бы это передеалть.. А с портом видно будет. Порт кстати пока не подводил...


 
Сергей М. ©   (2006-10-16 11:06) [98]


> Kolan ©   (16.10.06 10:56) [97]


> Смешно конечно звучит: Чтобы форма не висла


Ты даже не представляешь, насколько это смешно)..

Чтобы форма "не висла", ты как раз и задействовал доп.поток.
А уж как работает этот твой доп.поток с тем или иным устройством - синхронно или асинхронно - форме (еще точнее - основному потоку) отныне абсолютно фиолетово.
Так что сам собой напрашивается вывод - асинхр.режим выбран тобой от балды и  сложность его прогр.реализации (ощутимо повышенная по отношению к синхр.режима) ничем пока не оправдана.


 
Kolan ©   (2006-10-16 11:13) [99]


> асинхр.режим выбран тобой от балды и  сложность его прогр.
> реализации (ощутимо повышенная по отношению к синхр.режима)
> ничем пока не оправдана.

Ну не оправдан, знаю что до конца не разобрался. Сделал по статье - акуратно. Работатет не подводит. Уже сделано, зачем менять?


 
Сергей М. ©   (2006-10-16 11:42) [100]


> Kolan ©   (16.10.06 11:13) [99]



> Сделал по статье - акуратно


suspend твой в доп.потоке - тоже по статье ?)


 
Kolan ©   (2006-10-16 11:54) [101]


> suspend твой в доп.потоке - тоже по статье ?)

Причем тут это??? Я понимаю ветку ниасилили :)

Мы тут говорим НЕ о ПТОКЕ ЧНЕНИЯ ИЗ ПОРТА(который ессно не спит), а о другом потоке, Который ищет в полученых из порта данных пакет.


 
Сергей М. ©   (2006-10-16 12:12) [102]


> Kolan ©   (16.10.06 11:54) [101]


> ветку ниасилили


Эт точно)
В ней много шуму из ничего.

Если не вдаваться в подробности изначально неразумно спроектированной тобой логики разделения функциональности приложения (между потоками ее процесса), то ответ на вопрос был уже дан, и он прост как 2х2:

try
 synchronize(...)
except
... //никаких re-raise, если отсутствует перехват и обработка исключений уровнем выше !
end;


 
Kolan ©   (2006-10-16 12:17) [103]

Может мне для передечи сообщения, чтобы все осталось внутри модуля и не трогало гл. форму, создать формочку прямо в TConnectionManager

Те
TConnectionManager = class
 FForm: TForm;


А получив пакет я его скопирую и пошлю сообщение

procedure TConnectionManager.PackageReceivedEvent(Sender: TObject;
Package: array of Byte);
begin
 //Копирую
 PostMessage();
end;


Нормальный маривант?


 
Kolan ©   (2006-10-16 12:30) [104]

и сообщени передать Self те указательна экземпляр TConnectionManager, а форма вызовет:
TConnectionManger(Pointer).ProsessPackage // Ну или как там правильно преобразовать указатель в объект.

В итоге дальше модуля с TConnectionManger дело не пойдет. И Synchronize закончится быстро. :)

Но ответа я дождусь, а то опять перепахивать все :)


 
Ketmar ©   (2006-10-16 17:46) [105]

бр-р-р. что-то мне подсказывает, что ты спроектировал софт "от балды", совершенно не представляя, зачем там потоки, и что они должны делать. и как, собственно, вся эта механика работает. сорри, но у всех вопросов лапы растут явно оттуда. есть предложение: выспаться, плотно подумать и переписать всё заново. %-)


 
Kolan ©   (2006-10-16 18:12) [106]


> бр-р-р. что-то мне подсказывает, что ты спроектировал софт
> "от балды", совершенно не представляя, зачем там потоки,
>  и что они должны делать. и как, собственно, вся эта механика
> работает.

Все же некоторое представление о том что там да как имею. :)


> Kolan ©   (16.10.06 12:17) [103]

Дык это брр?

Итак я получил пакет. Как мне сделать дальше. Как спроектировать?

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


Система примерно такая
1. Есть главный менеджер в который композитно входит менеджер измерений(Он знает логику измерения).
2. В менеджере измерений есть менеджер устройства, который знает о протоколе.
3. Менеджер устройства использует менеджер связи(TConnectionManager), который обрабатывает данные и отправляет в порт.

Так вот форма в лучшем случае знает о Главном менеджере. Как быть? Сообщение посылать неудобно.

Как перепроектировать?


 
Kolan ©   (2006-10-16 18:22) [107]

Те я ка бы последовательно пользуюсь паттерном фасад.


 
Kolan ©   (2006-10-16 19:13) [108]

Короче, потом не говорите, что плохо  :)
TConnectionManager - точно должен быть фасадом. У него всего две функции предать пакет и выдать принятый, а там хот через сеть может передаваться. Делаю короче через окно(окно-поле этого менеджера) и сплю спокойно...


 
Percent   (2006-10-16 19:39) [109]

1. Есть главный менеджер в который композитно входит менеджер измерений(Он знает логику измерения).
2. В менеджере измерений есть менеджер устройства, который знает о протоколе.
3. Менеджер устройства использует менеджер связи(TConnectionManager), который обрабатывает данные и отправляет в порт.


И в чем проблема? Каждый менеджер пусть обрабатывает свой участок работы.
1. Менеджер связи - отсылает пакеты и ждет приходящих пакетов. Сделай у него события OnConnect, OnDisconnect, OnPacketReceived, OnError. И метод отправки пакета.
2. Менеджер устройства - пусть собирает пакеты для отправки и разбирает пакеты при пролучении.
3. Менеджер измерений пусть анализирует принятую информацию. И подготавливает данные измерений.

Ты бы хоть бы название софта озвучил бы. И логику его работы описал. То есть, для чего это все?


 
Leonid Troyanovsky ©   (2006-10-16 19:42) [110]


> Kolan ©   (16.10.06 18:12) [106]

> Как перепроектировать?


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

type
 EThreadException = class(Exception);

 TMyThread = class(TThread)
   procedure Execute; override;
 private
   ..
   Error: Exception;
   procedure ShowError;
   procedure ShowResult;
 end;

procedure TMyThread.ShowExcept;
begin
 Application.ShowException(Error);
end;

procedure TMyThread.Execute;
begin
 while not Terminated do
   try
      ..
      raise EThreadException.Create("..."); // если что-то не так
      ..
      Synchronize(ShowResult); // показываем результат
      ..
   except
     on E: EThreadException do // мы знаем, как исправить ситуацию
       begin
         Error := E;
         Synchronize(ShowExcept); // если нужен показ
         {корректирующие действия}
       end;
     on E: Exception do  // мы не знаем, как реагировать на другие ошибки
       begin
         Error:= E;
         Synchronize(ShowExcept); // показываем исключение
         Terminate; // завершаем поток
       end;
   end;
end;


Что произойдет, если исключение возникнет в ShowResult?
Если внутри метода нет обработчиков, исключение попадет в except потока. Если это известное исключение (EThreadException), то его можно
обработать и, возможно, поток продолжит работу.

Для неизвестных исключений продолжать поток смысла нет.

Схема может быть использована непосредственно
для тех потоков, которые отзываются на Termianate.
А, например, поток, ожидающий в ReadFile ввода не в состоянии
реагировать на установку Terminated, т.е., нуждается в
дополнительных управляющих сигналах.

Ну, и не должны потоки быть suspended.
Это для потока не рабочее состояние, а скорее отладочное.

--
Regards, LVT.


 
Kolan ©   (2006-10-16 20:01) [111]


> И в чем проблема? Каждый менеджер пусть обрабатывает свой
> участок работы.
Именно так они  и работают...


> Leonid Troyanovsky ©   (16.10.06 19:42) [110]
>
>

Благодарю. Идея понятная. Буду пользоваться.
Но в денном случае, опираясь на ваш код. В
Synchronize(ShowResult); мне надо лишь отправить пакет дальше... и Тут же вернуться. Те никаких исключений в потоке не будет.

Вот я и спрашиваю можно ли замутить с формой?


> Ну, и не должны потоки быть suspended.
> Это для потока не рабочее состояние, а скорее отладочное.
>

Буду медетировать на это.


 
Percent   (2006-10-16 20:06) [112]

Вот я и спрашиваю можно ли замутить с формой?

Перефразируй, пожалуйста...


 
Kolan ©   (2006-10-16 20:10) [113]

Вот короче этот злашастный менеджер целиком:

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

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


 
Kolan ©   (2006-10-16 20:32) [114]

Делаю форму:

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

Как правильно это сделать(Подчеркнутое)?


 
Leonid Troyanovsky ©   (2006-10-16 20:39) [116]


> 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:44) [117]


> Если не нужна синхронизация (обработки пакета),
> то поток может распределить блок нужного размера путем GetMem,
>
> заполнить его данными и отправить его адрес (размер) путем
> Post(Thread)Message главному потоку в форме WM_USER+x.
> Главный же поток, по окончании обработки, удалит блок.

Дааа, может Можно и не через GetMem, Но сообщение прийдет в форму.
А обработанное должно быть в TConnectionManager, а от Формы до него ого го см[106]. Что бы это сотворить надо предавать хендл формы во все эти классы.

И еще форма узнает о том что существует какой-то поток, какие-то байты нафиг её это надо, её дело нажатия на кнопочки обработать...


 
Kolan ©   (2006-10-16 20:46) [118]

В жизни не создавал форм динамически, при

FSynchronizationForm := TSynchronizationForm.Create(nil);

получаю resourse TSynchronizationForm not found. Как избавится?


 
Leonid Troyanovsky ©   (2006-10-16 20:58) [119]


> Kolan ©   (16.10.06 20:44) [117]

> А обработанное должно быть в TConnectionManager, а от Формы
> до него ого го см[106].


Ну, я так далеко не заглядывал :)
Сделай компонент, который, с одной стороны, будет лежать
на форме (и знать, как с ней взаимодействовать), а, с другой
стороны - создаст поток и тоже будет с ним взаимодействовать.
Если хочется, то можно снабдить компонент окном, на манер TTimer,
в которое и будет осуществляться PostMessage.

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2006-10-16 21:02) [120]


> Kolan ©   (16.10.06 20:46) [118]

> получаю resourse TSynchronizationForm not found. Как избавится?


Создавай потомка TForm.
Или, если нужно окно (невидимое), а не форма - AllocateHwnd.

--
Regards, LVT.


 
Kolan ©   (2006-10-16 21:02) [121]


> Сделай компонент, который

А так как я предлагаю нельзя?


 
Kolan ©   (2006-10-16 21:08) [122]

Создавай потомка TForm.


Ну, а я че делаю...

TSynchronizationForm = class(TForm)
public
  procedure SXPackageReady(var Msg: TMessage); message SX_PACKAGEREADY;
end;



> Или, если нужно окно (невидимое), а не форма - AllocateHwnd.

Посмотрю.


 
Kolan ©   (2006-10-16 21:11) [123]


> AllocateHwnd

О вроде то что надо.. Шас испробую.


 
Leonid Troyanovsky ©   (2006-10-16 21:15) [124]


> Kolan ©   (16.10.06 21:02) [121]

> > Сделай компонент, который
> А так как я предлагаю нельзя?


Можно, наверное.

Но, для того, чтобы делать нечто обобщающее, скажем,
аналог TDataSource как промежуточной абстракции
между слоями, представлениями и т.п., нужно наработать
некий материал, пищу для ума, дабы понять, что полезно,
а что лишнее.

Да и неплохо осознавать, делается ли нечто одноразовое,
или вещь на каждый день.

--
Regards, LVT.


 
Kolan ©   (2006-10-16 21:18) [125]


> Да и неплохо осознавать, делается ли нечто одноразовое,
> или вещь на каждый день.

На каждый день. Этот менеджер связи - вообще универсальная штука. Я его вставляю во все проекты...


 
Kolan ©   (2006-10-16 21:20) [126]

Вроде наваял с AllocateHwnd. Только незнаю как ссылку на объект в сообщении передать:
http://delphimaster.net/view/2-1161018380/


 
Kolan ©   (2006-10-16 21:28) [127]

:) Получилось, вроде. Правдо AV, шас поотлаживаю :)


 
Leonid Troyanovsky ©   (2006-10-16 21:31) [128]


> 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:33) [129]


> Leonid Troyanovsky ©   (16.10.06 21:31) [128]
>
>

Ааа вот как надо, а я генофонд глянул и не че там не понял :) С AllocateHWND ИМХО приятнее тем более для этого оно и нужно :)


 
Kolan ©   (2006-10-16 21:41) [130]

Убейте меня пожалуйста. Теперь 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:51) [131]

Аааа это из-за интерфейса, а я уже странно смеяться стал.

Из за исключения Package = nil. А это что приведет к AV вот тут?:
Package: IPackage


 
Kolan ©   (2006-10-16 22:36) [132]

Вообщем тема закрыта успешно. Всех благодарю, особенно Ketmar и Leonid Troyanovsky за вправление мозгов :)



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

Форум: "Основная";
Текущий архив: 2006.11.26;
Скачать: [xml.tar.bz2];

Наверх





Память: 1.06 MB
Время: 0.05 c
15-1163044314
Slider007
2006-11-09 06:51
2006.11.26
С днем рождения ! 9 ноября


5-1144329234
Alex Romanskiy
2006-04-06 17:13
2006.11.26
Компоненты для работы с MySQL


2-1162912857
==Dark_lord==
2006-11-07 18:20
2006.11.26
Проблема с кодировкой...


4-1153121367
Чапаев
2006-07-17 11:29
2006.11.26
Буква загрузочного тома


2-1162811723
Khabibulin
2006-11-06 14:15
2006.11.26
Нарисовать треугольник в Pascal е





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский