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

Вниз

Чтение из Com порта используя поток.   Найти похожие ветки 

 
Kolan ©   (2005-06-01 15:01) [0]

Здравствуйте,
 Делаю класс работы с портом. Всё ясно кроме чтения в отдельном потоке. Просто не понимаю и всё. Вот пример:

Написал два класса - собственно ComPort и для потока.

TComPort = class
 private
   PortHandle: THandle;
   {...}
   FReadThread: TReadComThread;
   {...}
   function StartReadThread: Boolean;
 protected
 public
   {...}
   function ReadByteArray(var Buffer: array of Byte; Length: Cardinal): Boolean;
 published
   {...}

 end;


TReadComThread = class(TThread)
 private
 protected
 public
   procedure Execute(PortHandle: THandle;
     Buffer: array of Byte; Length: Cardinal; TimeOut: Cardinal); override;
 end;


procedure TReadComThread.Execute(PortHandle: THandle;
 Buffer: array of Byte; Length: Cardinal; TimeOut: Cardinal);
var
 ComStat: TComStat;
 dwMask, dwError: DWORD;
 OverRead: TOverlapped;
 dwRead: DWORD;
begin
 OverRead.hEvent := CreateEvent(nil, True, False, nil);
 if OverRead.hEvent = 0 then
 begin
   //AddError(ceReadEvent);
 end;

 FreeOnTerminate := True;
 while not Terminated do
 begin
   if not WaitCommEvent(PortHandle, dwMask, @OverRead) then
   begin
     if GetLastError = ERROR_IO_PENDING then
       WaitForSingleObject(OverRead.hEvent, INFINITE)
     else
     begin
       //AddError(ceWatingPortEvent);
     end;
   end;

   if not ClearCommError(PortHandle, dwError, @ComStat) then
   begin
     //AddError(ceClear);
   end;

   dwRead := ComStat.cbInQue;

   if dwRead > Length then
   begin
     if not ReadFile(PortHandle, Buffer, dwRead, dwRead,@OverRead) then
     begin
       //AddError(ceRead);
     end;
     {Use Тут автор примера предлагает обработать данные}    end;
 end; {while}
end;

В примере, по которому я всё это сделал предлагается обработать всё в потоке как я понял.

А я так не хочу. Я хотел бы в этом отдельном потоке подождать некоторое время. По всей видимости это можно задать тут:
WaitForSingleObject(OverRead.hEvent, INFINITE)
Прочитать из порта. И вернуть прочитанные байты.

Кроме того я непойму вот что: для чтения мне нужен Хендл порта, который описан в другомм классе. Как мне его передать в поток...

Подскажите что я непонимаю? И как сделать правиль то, что я хочу.


 
Digitman ©   (2005-06-01 15:16) [1]

начни стого, что приведенный тобой код даже скомпилирован быть не может - у TThread вирт.метод Execute не имеет параметров, соответственно и в твоем перекрытом методе их быть не должно


> Как мне его передать в поток


например, параметром Create - конструирующего объект метода


 
Kolan ©   (2005-06-01 15:33) [2]


> Digitman ©   (01.06.05 15:16) [1]

Пардон там нет override. Да это я просто чтобы остальные функции проверить написал с параметрами. Чтобы компилироваллнось.


> например, параметром Create - конструирующего объект метода

То есть вы предлагаете сделать поле с хендлом порта и когда я его создаю(поток)из экземпляра TComPort передовать туда Хендел.

Как в таком случае должен работать поток? Мне надо для записи его создовать/удалять каждый раз? Скореевсего будет долго. А если поток всега работает то номер порта может изменится и что тогда?...

Главное как вернуть байты после того как они прочитаны?

Те в классе TComPort я бы хотел сделать функцию Read допустим. Пусть поток всегда запушен и как только что то появилось возврашает результат. Или вот как? Не могу врубится.

Вообшем мне надо чтобы чтение из порта не вешало основной поток.


 
Digitman ©   (2005-06-01 15:58) [3]


> вы предлагаете сделать поле с хендлом порта и когда я его
> создаю(поток)из экземпляра TComPort передовать туда Хендел


именно.
но это только один из вариантов.


> Как в таком случае должен работать поток? Мне надо для записи
> его создовать/удалять каждый раз?


вовсе не обязательно, можно один и тот же поток использовать


> Скореевсего будет долго


в смысле ?


> если поток всега работает то номер порта может изменится
> и что тогда?


и тогда нужно каким-либо образом известитбь поток о смене рабочего хэндла

это не вопрос

реализуй в своем поточном классе метод ReplaceCOMHandle(NewHandle: THandle)


> Вообшем мне надо чтобы чтение из порта не вешало основной
> поток


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

а у тебя - асинхронный режим (я вижу что overlapped-механизм тобой таки используется)

так что можно вообще и без доп.потока обойтись

а зачем тебе велосипед изобретать ? есть жа в сети куча всякоразных готовых компонентов для работы с ком-портами , в т.ч. и в асинхр.режиме !
бросил компонент на форму, назначил обработчик OnRead - и всех делов) ... работай себе спокойно в осн.потоке, а как только в ком-порте будут доступны какие-то данные, компонент вызовет твой обработчик, где ты преспокойно прочитаешь эти данные из порта


 
Сибиряк   (2005-06-01 20:14) [4]

На низком уровне из компорта, да и из лпт тоже следует читать в цикле. И ждать сигнала с определенной ноги и анализировать номер ноги. Таже следует предусмотреть вариант выхода из цикла.


 
YurikGL ©   (2005-06-01 21:14) [5]

http://www.kamlit.ru/docs/journals/cd/cd22/off-line/pr/22/article_15.php.htm

Если не ошибаюсь, разобрана работа с COM из потоков

Кстати, я в свое время скачал какой-то компонент и горя не знал :)


 
Германн ©   (2005-06-02 02:12) [6]

Я вот чего не понимаю в упор!

А на кой черт нужна работа с COM-портом в сихронном режиме? При том, что вся логика того же Дельфи сводится к реализации обработчиков событий. А для COM-порта эти события (прерывания) существовали исторически, по крайней мере с конца 80-х прошлого века. Да и сейчас они (эти события) прекрасно реализованы, ну хотя бы в AsyncPro, которая ныне является условно бесплатной, но с исходниками.


 
Defunct ©   (2005-06-02 03:45) [7]

> Германн ©   (02.06.05 02:12) [6]
> А на кой черт нужна работа с COM-портом в сихронном режиме?
И мне тоже интересно.

А еще интересно другое, что бесит гораздо сильнее. Почему в системе на уровне файловых операций не реализован простой механизм, по которому можно было бы проверить "есть данные для считывания или нет". Ведь еще с начала 80-х была возможность проверить состояние порта "байт данных получен".

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


 
Evgeny V ©   (2005-06-02 07:20) [8]


> Defunct ©   (02.06.05 03:45) [7]
> > Германн ©   (02.06.05 02:12) [6]
> > А на кой черт нужна работа с COM-портом в сихронном режиме?
> И мне тоже интересно.
>
> А еще интересно другое, что бесит гораздо сильнее. Почему
> в системе на уровне файловых операций не реализован простой
> механизм, по которому можно было бы проверить "есть данные
> для считывания или нет".


Конкретно для случая COM порта возможность подсмотерть сколько данных в буфере есть, смотри ClearCommError -  COMSTAT - cbInQue. Анологичные операции (функции), хоть и другие по имени и реализации,  подсматривания количества данных в буфере реализованы и для других коммуникационных вещей, которые могут воспользоваться ReadFile, для именованных и неименованных каналовканалов например, сокетов


 
Defunct ©   (2005-06-02 07:42) [9]

> Evgeny V ©   (02.06.05 07:20) [8]
Спасибо!
Очень полезная информация!
Просто диву давался после прочтения статей в инете на эту тему, сплошь и рядом ASyncPro да "замирающий" ReadFile.


 
Digitman ©   (2005-06-02 08:12) [10]


> Defunct ©   (02.06.05 07:42) [9]


> "замирающий" ReadFile


да не "замирает" он вовсе)... если с умом использовать ..
есть же overlapped-режим !
а не нравится overlapped ? еще одна альтернатива есть - ReadFileEx со своими колбэками ..


 
Defunct ©   (2005-06-02 09:51) [11]

> ClearCommError -  COMSTAT - cbInQue.
> есть же overlapped-режим
> ReadFileEx

Если выбирать между этими тремя способами. Первый мне наиболее по душе. Как раз то чего так не хватало.


 
Digitman ©   (2005-06-02 10:03) [12]


> Defunct ©   (02.06.05 09:51) [11]


> Первый мне наиболее по душе. Как раз то чего так не хватало


а я предпочел бы коллбэки в Read/WriteFileEx .. в колбэк-функцию передается достаточная инф-ция и о размере прочитанных/записанных данных и об ошибке, если она имела место быть ...

правда, под Маздаем для СОМ-дивайсов эти ф-ции не м.б. задействованы


 
Германн ©   (2005-06-02 14:00) [13]

2 Defunct ©   (02.06.05 03:45) [7]
>> AsyncPro
>С портами ОС должна работать нормально, а не "по-козьи", что >вызывает потребность во всяких левых комонентах.

Ну это вы, батенька, зря наехали на увы почившую ныне в бозе TurboPower Software. Мы с ней прожили почти всю свою сознательную жизнь.


 
Koan   (2005-06-04 14:09) [14]

Здравствуйте,
 
> именно.
> но это только один из вариантов.

Я понял так и сделал.

> а зачем тебе велосипед изобретать ?

Да компонеты уменя есть. Я хочу из этого dll сделать. Чтобы подключать можно было.

Кстати а это нормальн если у меня компонент на форме, а я сделал класс интерфейса устройства и программы.

И там везде запись выгдлядит:
MainForm.Comm1.WriteByte(B); ...
Это по моему не правильно?

Вот я сделал поле класа потока FData туда кладу байты если они есть
dwRead := ComStat.cbInQue;

   if dwRead > 0 then
   begin
     if not ReadFile(FPortHandle, FData, dwRead, dwRead,@OverRead) then


Как теперь классу ComPort сообщить что считанно с порта и можно забирать.

PS
Причем общение такое: записал пару байт считал пару - тройку.


 
Defunct ©   (2005-06-04 19:55) [15]

> Koan  

CallBack"ом - назначить событие OnRead.



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

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

Наверх




Память: 0.52 MB
Время: 0.043 c
8-1110308590
New37th
2005-03-08 22:03
2005.06.29
Люди, хэлп ми плиз, спрайты!!!!


1-1117622833
chili
2005-06-01 14:47
2005.06.29
Подскажите как работать с libpq.dll для 8.0?


1-1117762854
dp200
2005-06-03 05:40
2005.06.29
FileName


8-1110281448
Vir_
2005-03-08 14:30
2005.06.29
Вывод текста в OpenGL


14-1117479218
NailMan
2005-05-30 22:53
2005.06.29
Надо есть правильные сладости! :-)))