Фоновый рабочий не работает

У меня есть приложение C#, с помощью которого я настраиваю параметры камеры Ethernet. Камера действует как сервер, а приложение — как клиент.

Есть 2 разъема для связи, один для передачи данных/команд - разъем данных (двусторонняя связь) и другой разъем для изображения, камера отправляет изображение через разъем изображения (односторонняя связь). Камера будет отправлять изображение через сокет изображения всякий раз, когда ей дается аппаратный триггер (непредсказуемо, когда придет аппаратный триггер).

Пользователь может настроить камеру, изменив значения в графическом интерфейсе. Когда пользователь изменяет параметр, приложение отправляет команду и данные на камеру через командный сокет и ожидает ответа (время ожидания приема составляет 5 секунд). Камера получает команду и отправляет ответ обратно. Графический интерфейс получает обновления пользователя, который успешно обновился.

Я поместил сокет изображения в фоновый рабочий. Бесконечный цикл while внутри него продолжает опрашивать изображение в сокете изображения, и всякий раз, когда изображение получено, оно отображается в графическом интерфейсе (я использую для этого делегат). Все хорошо :)

Теперь, когда на камеру придет триггер, она отправит изображение. В тот же момент пользователь изменяет параметр, приложение отправляет команду/данные и ждет ответа. Камера получит команду только после полной отправки изображения. Что происходит, так это то, что фоновый рабочий (который получает изображение) не работает, когда приложение ожидает ответа на команду. Таким образом, пользовательский интерфейс ожидает ответа в командном сокете, а камера отправляет изображение в сокет изображения, а пользовательский интерфейс не получает изображение, поскольку фоновый рабочий процесс не запущен. Это становится тупиком, и в командном сокете происходит тайм-аут (5 секунд) :(.

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

Спасибо, Вишну


person Vishnu    schedule 01.02.2011    source источник


Ответы (2)


Я бы посоветовал вам убедиться, что делегат, используемый для обновления изображения из фонового рабочего процесса, вызывается асинхронно (используя BeginInvoke). Синхронный вызов может вызвать блокировку.

person Johann Blais    schedule 01.02.2011

Не видя кода, немного сложно понять это, но я подозреваю, что проблема связана с блокировкой пользовательского интерфейса приложения в ожидании ответа.

Какой поток он ожидает после отправки команды? Если это UI-поток с плохим дизайном, UI-потоку не нужно ничего ждать.

Создайте еще один поток, который используется для связи через сокет команды/данных. Пользовательский интерфейс может просто помещать команды в ConcurrentQueue<T> или BlockingCollection<T>. Поток, которому принадлежит сокет данных, будет потреблять команды из очереди, отправлять их на камеру, ждать до пяти секунд, а затем отправлять сообщение обратно в пользовательский интерфейс (используя Invoke). Этот поток будет сериализовать весь доступ к сокету команды/данных, чтобы гарантировать, что только одна команда активна в любой момент времени.

person Ian Mercer    schedule 01.02.2011
comment
Спасибо за ответ. Я попробую этот подход, который вы предложили, и вернусь. Как вы сказали, командный сокет ожидает в потоке пользовательского интерфейса. - person Vishnu; 01.02.2011
comment
Я использую VS2008. Есть ли способ сделать это в этом? - person Vishnu; 17.02.2011