Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Асинхронный ввод-вывод, поиск не особо помог 
V
    Опции темы
jorikdima
Дата 12.11.2008, 11:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 107
Регистрация: 18.1.2008
Где: Там, где Зенит

Репутация: нет
Всего: нет



Добрый день.

В общих словах задача следующая. Есть прием данных из последовательного порта. Вообще говоря принимаю быйты пачками, но в данном контексте невадно, можно считать, что реальзуется побайтовое чтение. Использую объект SerialPort, и вроде у него есть все нужные функции чтения записи, но использую я его только для открытия закрытия порта, а непосредственно данные получаю, используя его свойство BaseStream. То есть открываю порт, при этом происходит создания объекта BaseSream и я его пользую. Причина этого состоит в том, что моя собственная функция анализа входных данных на вход принимает объект типа Stream для того, чтоб в будущем легко можно было работать с данными не только из порта, но и из файла, MemoryStream и пр.
Так вот. Проблема в том, что я, во-первых, могу захотеть в любой момент остановиться и не парсить входной поток баит, либо в любой момент поток может просто прекратиться насередине (девайс, подключенный к порту прекратит слать данные по неизвестной причине). Что при этом произойдет. При этом функция ReadByte() объкта BinaryReader (наследник Stream) просто подвиснет. Чтоб это было не критичным мне казалось, что будет достаточным всю мою функция парсинга поместить в отдельный Thread, использую например BackgroundWorker. Таким образом не будетподвисать основной поток на время чтения, ну и даже если чтение остановится по причине отсутствия данных, все равно основному процессу это не помешает.
Но тут появилосьодно НО. Дело в том, что для того, чтоб корректно завершить BackgroundWorker нужно в самом DoWork обработать условие СфтсудфешщтЗутвштп и если оно истинное, то выйти из цикла парсинга. Но какя это сделаю если у меня мой Thread (который создал BackgroundWorker) спит в функции ReadByte() объкта BinaryReader? Впринципе это мой вопрос номер раз.
Пытаясь сомостоятельно ответить на него я наткнулся на асинхронные операции ввода-вывода. Прочитал про методы BeginInvole EndInvoke. Понял, что пожалуй это то или почти то, что мне нужно, но возник вопрос. Вот представим, что в моей конфигурации я в методе DoWork, в котором у меня реализован парсер и в котором нескольео раз происходит чтение из потока, я сделаю следующее. Я буду вызывать синхронные методы Read асинхронно. А посде вызова в цикле буду проверять результат выполнения и считать время. Если время больше таймаута, то... а вот что? Что тогда? Не вызывать EndInvoke (ведь если его вызовешь, то подвиснешь), но что делать с тем потоком (уже третьим после основного и BackgroundWorker) в котором запустился Read? Как его прибить и прибить ли. Ведь я даже не могу ничего сделать с объектом Stream из которого происходит попытка чтения, не могу его прибить и не могу даже без исключения программу закрыть. Это мой вопрос номер два.

PS Вообще говоря, я мог просто использовать метод Read класса SerialPort, там можно организовать таймаут, а это именно то, что мне нужно. Но как я сказал выше, в будущем мен понядобится работать с любыми потоками, а не только с данными из порта, а метод  ReadByte() класса BinaryReader не позволяет иметь таймаутов.

PPS Может уже есть реальзации классов наследников либо от Stream либо от BinaryReader, что предпочтительнее, имплементирующие чтение по таймаутам, чтоб велосипед не изобретать? Ведь это же сделано в SerialPort.
Спасибо.
PM MAIL   Вверх
mr.DUDA
Дата 12.11.2008, 12:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



На первые два вопроса можно ответить использованием обычного Thread, который можно обрубить в любой момент с пом. thread.Abort(); thread.Join(timeOut);


--------------------
user posted image
PM MAIL WWW   Вверх
jorikdima
Дата 12.11.2008, 12:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 107
Регистрация: 18.1.2008
Где: Там, где Зенит

Репутация: нет
Всего: нет



Спасибо. Странно, а помему так же жестоко и просто нельзя вырубить BackgroundWorker? Почему есть требование, а не просто возможность, его самостоятельного завершения?
PM MAIL   Вверх
Lazin
Дата 12.11.2008, 12:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: нет
Всего: 154



можно использовать асинхронную запись - чтение, это когда ты вызываешь функцию, например записи в файл (BeginWrite), и передаешь туда callback, функция возвращает управление сразу-же, а потом, когда данные будут записаны, будет вызван твой callback. Это наиболее прогрессивный подход smile 
PM MAIL Skype GTalk   Вверх
jorikdima
Дата 12.11.2008, 12:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 107
Регистрация: 18.1.2008
Где: Там, где Зенит

Репутация: нет
Всего: нет



Цитата(Lazin @ 12.11.2008,  12:31)
можно использовать асинхронную запись - чтение, это когда ты вызываешь функцию, например записи в файл (BeginWrite), и передаешь туда callback, функция возвращает управление сразу-же, а потом, когда данные будут записаны, будет вызван твой callback. Это наиболее прогрессивный подход smile

Это принципиально ничем не отличается от мною выше написанного. Ибо можно задать тот же вопрос: А если данные не будут записаны и я это увижу по таймауту, то что мне делать с тем процессом в котором будет происходить чтение? Я так понимаю, что прибить его не удасться ибо к нему просто нету доступа. То что советует Мр Дуда, подходит, впринципе, там как раз есть доступ к процессу, так как программист сам его и создает.
PM MAIL   Вверх
mr.DUDA
Дата 13.11.2008, 11:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Цитата(jorikdima @  12.11.2008,  12:19 Найти цитируемый пост)
Странно, а помему так же жестоко и просто нельзя вырубить BackgroundWorker? Почему есть требование, а не просто возможность, его самостоятельного завершения?

Ну наверное потому что это не комильфо рубить поток на середине его выполнения, по-хорошему ждать надо.  smile 




--------------------
user posted image
PM MAIL WWW   Вверх
jorikdima
Дата 13.11.2008, 14:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 107
Регистрация: 18.1.2008
Где: Там, где Зенит

Репутация: нет
Всего: нет



Оказалось я дятел smile smile smile Надо внимательнее читать MSDN. Метод Read класса BinaryReader не вешает поток до тех пор пока не прочитает все заданное количество байт. А он читает все что есть, но не больше заданного. Если не хватает, то в возвращаемом значении указывается число прочитанных байт и его можно сравнить с заданным, определив недобор smile

Спасибо mr.DUDA!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0586 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.