Форум: "Основная";
Текущий архив: 2005.06.29;
Скачать: [xml.tar.bz2];
ВнизЧтение из 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;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.06 c