2010-10-26 2 views
2

Прежде всего, я хотел поблагодарить сообщество. В последнее время ты очень помог! Обычно мне даже не нужно задавать вопросы, потому что они уже есть. Теперь у меня есть проблема, которая напрямую не связана с кодом, а сама программа.Лучшие практики? Подождите, пока не получите или не поднимет событие при приеме

Я работаю с чипом FTDI и программированием на C#, где приложение ПК действует как Мастер (отправляет запросы) миллисекундов, но в любом случае потребуется некоторое время. Я застрял в концептуальном/философском вопросе дизайна кода.

После отправки запроса я должен сразу ответить на вопрос (проверяя также тайм-аут), или я должен постоянно контролировать вход (BackgroundWorker powered) и поднять событие после получения ввода данных? Что бы вы порекомендовали, что по вашему опыту. Какие факторы я должен учитывать при выборе?

Я никогда не изучал программный дизайн самого программирования, поэтому я думаю, что мне не хватает базового на этом, но это личный проект, над которым я работаю, и я уверен, что мне понравятся некоторые отзывы/указатели на это от вас, ребята.

Спасибо!

ответ

0

Моим предпочтительным решением в этом случае было бы выдать запрос в асинхронном режиме (так, чтобы вы получили обратный вызов по событию, которое срабатывает, когда оно завершено), а также реализовать время асинхронного использования с использованием стандартных .Net-механизмов, которые перезвонит вам, если появится, что подчиненный не отвечает. Таким образом, вы просто запускаете запрос и таймер, а затем можете продолжать делать больше работы, не требуя каких-либо других потоков для обработки результатов.

Вам нужно будет убедиться, что одновременный тайм-аут и время отклика обработаны с использованием механизма блокировки, так что вы точно знаете, вы отключаете или обрабатываете ответ.

Старайтесь избегать опроса и мониторинга ввода, если только ваш подчиненный API не допускает детерминированной генерации событий отклика.

+0

Я отлично себя чувствовал, пока вы не сказали «используя механизм блокировки». Я пойду гугл и вернусь.Во всяком случае, ведомый фактически не создает события, но FTDI Chip позволяет подписку EventWaitHandle, которую я мог бы использовать для создания события на полученных байтах. То, что я не хочу делать, - это оставаться в цикле до тех пор, пока WaitEventHandle не загорится, когда я потеряю ответ GUI. Благодарю. –

+0

@Jazz - простой способ обеспечить однопоточный доступ - это определить «статический объект mylock = new object();» в одном из ваших классов, а затем использовать «блокировку (mylock)» вокруг кода в вашем таймере и get- ответные обратные вызовы, которые не должны выполняться одновременно. –

+0

, когда вы имели в виду «используя стандартные механизмы .net», вы имеете в виду system.timers.timer? –

0

Обычно я работал бы с асинхронным подходом на низкоуровневом сайте и, возможно, накладывал на него некоторый механизм синхронизации. Вот примерный подход, если вы получаете фрагменты данных, и вам нужно объединить эти фрагменты в целое сообщение.

Итак, на низкоуровневом сайте внедряйте BackgroundWorker, который постоянно проверяет входящие данные и поднимает какое-то событие, если вы что-то получили и поместили это в событие.

Над этим кто-то слушает события входящих данных и помещает все эти (возможно) фрагменты во внутреннюю очередь. Там он проверяет, есть ли у него достаточное количество данных для полного сообщения, возможно, некоторые проверки ошибок и т. Д. Если у него есть полное сообщение, оно поднимет событие, чтобы отправить это сообщение всем слушателям.

В дополнение к этому ставится еще один класс, который следит за сообщениями и реагирует на них. Этот класс, возможно, реализует некоторый механизм синхронизации, чтобы следить за тем, соответствует ли входящее сообщение тому, что должно было произойти заранее.

Я думаю, что этот дизайн позволяет легче реагировать на данные, которые поступают, когда вы чего-то не ожидаете. И когда вам нравится останавливаться, вам не нужно ждать каких-либо тайм-аутов (может быть, очень малая, которую использует BackgroundWorker на низком уровне, чтобы вытащить данные из источника, который не поддерживает механизм событий).

+0

Это именно то, что я планировал сделать. Я думаю, что использование этого подхода позволяет мне забыть о проверке таймаута, но мой главный аргумент здесь в том, как узнать, готов ли я отправить другой запрос? Мне нужно что-то вроде Eventwaithandle, чтобы ждать bgw или счетчик для bgw? –

+0

кстати. сторона низкого уровня позволяет повысить уровень событий. Но даже так, могу ли я ждать события (в том же потоке)? afaik, eventwaithandle работает только при подписке на событие в других потоках? (пожалуйста, исправьте, если не так) –