Мне уже посоветовали и описали как сделать на AutoResetEvent и BlockingCollection. Реализовал при помощи первого. Ваш вариант муторнее. Да и Mutex же используются между процессами, а не потоками.
Mrrl: Я тут сейчас поигрался c AutoResetEvent. Вроде все хорошо работает. И не будет ошибок.
Правда у меня вопрос возник, почему если вызвать 2 или более раз метод Set, то блокировка пройдет только на второй вызов WaitOne?
Идея с флагом не совсем не нравится. Тк я опять должен в коде предусматривать наличие такого вот бага. Эй смотри я щас тебе буду слать, смотри не засыпать, дальше шлю команды в список. После чего убираю флаг.
Вот на счет событий было бы интересно. Но тут надо думать как это делать.
Если поток внутри цикла отправки команд, то ничего делать не надо.
Если поток спит, то разбудит его только Interrupt.
А вот что слать ему, если он еще не спит, но уже и прошел проверку цикла и выходит\вышел из него?
Алексей Немиро: Я нигде не писал про кучу создаваемых потоков. У меня одновременно только один поток отвечает за отправку команд в COM порт. То что вы написали имеет отличие только в типе коллекции. Вы взяли простейший лист, а я очередь для синхронного доступа. Я так понимаю вы этот код предлагаете мне запихать в AddCommand?
Алексей Немиро: Ну у меня в коде так и написано. Поток для отправки берет команду, отправляет ее и удаляет. Если нет команд в очереди, то поток закрывается. При добавлении команды смотрю, есть ли действующий поток для отправки. Если есть, то ничего не делаю, если нет, то его создаю. И тут то и может появиться ошибка, я же все описал.
Получилось очень даже быстро. Время импульса 20 миллисекунд. Я обращаюсь к плате каждые 0.002 миллисекунды. Можно теперь даже устройство чуть изменить. Причем мне кажется, что можно еще ускорить, если использовать не .NET, а С++. А уж если и сам драйвер переписать, то можно будет делать прерывания, благо на плате они поддерживаются, судя по схеме.
Для абстракции. Два класса просто выдают инфу о том, что данные на входе изменились. Другой класс представляет подключаемое устройство и там будет идти обработка этих значений для генерации более выскоуровневых событий. Дальше прога уже будет использовать класс подключаемого устройства.
То как ты мне рекомендуешь, то мне везде потребуется работать уровне самой платы и если к примеру интерфейсы для ее доступа или формат выдаваемого значения кардинально изменится, то мне потребуется менять всю прогу. Чем я сейчас и занимаюсь. Драйвера для платы кардинально изменились, по другому ее настраиваем и данные выдает в совершенно по другому. Старые драйвера использовать нельзя, тк они WinXP only, а ее уже не продают.
Чуть позже устройство приема будет уже заменено и менять всю прогу мне нет желания. А еще в планах возможность подключения нескольких устройств. Спасибо не хочу делать одну и ту-же работу по несколько раз. Предусмотри разработчики такое развитие событий ранее, у меня было бы гораздо меньше работы сейчас.
Ну раньше было написано на VB.NET .NET 2.0. Работало более менее. Качество кода отвратительное и сделано через критические секции синхронизация. Если у меня щас получится сделать по шустрее, то будет хорошо.
Устройство, что подключено к плате сбора данных будет максимум менять инфу раз 600 в минуту. Но вот плата, которая эти данные считывает и уже выдает в цифровом формате не имеет режима прерывания. Я могу только обращаться к ней с командой чтения текущего значения. Что бы зафиксировать момент, когда придет импульс на эту плату мне нужно в бесконечном цикле к ней обращаться и сверять данные. Если такой цикл повесить в главном потоке, то он повесит всю систему. А у меня таких платы две штуки. Учитывая, что компы щас по 2 ядра с гиперпоточностью минимум, а то и 4 полноценных ядра имеют, то мне лучше каждую плату вытащить в отдельный поток. И да я знаю, что все это очень убого выглядит, но выбросить эти платы я не могу в текущем проекте, благо в будущем их уже не будет.
Синхронизация данных не нужна мне. У меня данные не будут приходить чаще 600 раз в минуту. А уж по полученному байту сгенерировать еще пару байт текущим компам не проблема.Добавление синхронизации только ухудшит время реакции. Мне по хорошему вообще нужно реальное время, но для этого ОС потребуется менять. Щас копаюсь с диспетчером, так вроде быстрее будет.