| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Общие вопросы по .NET и C# > Асинхронный ввод-вывод |
| Автор: jorikdima 12.11.2008, 11:03 |
| Добрый день. В общих словах задача следующая. Есть прием данных из последовательного порта. Вообще говоря принимаю быйты пачками, но в данном контексте невадно, можно считать, что реальзуется побайтовое чтение. Использую объект 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. Спасибо. |
| Автор: mr.DUDA 12.11.2008, 12:08 |
| На первые два вопроса можно ответить использованием обычного Thread, который можно обрубить в любой момент с пом. thread.Abort(); thread.Join(timeOut); |
| Автор: jorikdima 12.11.2008, 12:19 |
| Спасибо. Странно, а помему так же жестоко и просто нельзя вырубить BackgroundWorker? Почему есть требование, а не просто возможность, его самостоятельного завершения? |
| Автор: Lazin 12.11.2008, 12:31 |
| можно использовать асинхронную запись - чтение, это когда ты вызываешь функцию, например записи в файл (BeginWrite), и передаешь туда callback, функция возвращает управление сразу-же, а потом, когда данные будут записаны, будет вызван твой callback. Это наиболее прогрессивный подход |
| Автор: jorikdima 12.11.2008, 12:35 | ||
Это принципиально ничем не отличается от мною выше написанного. Ибо можно задать тот же вопрос: А если данные не будут записаны и я это увижу по таймауту, то что мне делать с тем процессом в котором будет происходить чтение? Я так понимаю, что прибить его не удасться ибо к нему просто нету доступа. То что советует Мр Дуда, подходит, впринципе, там как раз есть доступ к процессу, так как программист сам его и создает. |
| Автор: jorikdima 13.11.2008, 14:47 |
| Оказалось я дятел Спасибо mr.DUDA! |