Асинхронный обработчик событий - flycapture от PointGrey
Я использую API-интерфейс FlyCapture Point Grey для управления некоторыми камерами. В общедоступном классе я реализовал весь начальный и инициализирующий код; далее _cam относится к ManagedGigECamera. Поскольку у меня 16 камер, я хочу, чтобы код был максимально быстрым, поэтому я хотел использовать задачи.
Вот код, который я использую:
_cam.StartCapture(AddressOf OnImageGrabbed)
.../...
Public Sub OnImageGrabbed(ByVal raw_image As ManagedImage)
Dim t As Task = Task.Run(Sub()
'save image to disk or whatever
End Sub)
t.Wait()
End Sub
Вышесказанное дает своего рода удовлетворение. Просматривая временные метки изображений, я вижу, что некоторые изображения сохраняются через несколько секунд после их захвата, и даже некоторые изображения вообще пропускаются... Я хотел убедиться, что каждый вызов OnImageGrabbed будет запускать новую задачу, и попытался выполнить следующее, но он сразу вылетает с "объектом, не установленным как экземпляр объекта" (не может отладить, код выполняется на удаленной машине)
_cam.StartCapture(AddressOf OnImageGrabbed)
.../...
Public Async Sub OnImageGrabbed(ByVal raw_image As ManagedImage)
Await Task.Run(Sub()
'save image to disk or whatever
End Sub)
End Sub
В общем, мои вопросы:
- Как я могу запустить обработчик событий асинхронно?
- почему, используя первый код, я получаю (как представляется) случайные задержки между каждым вызовом OnImageGrabbed? Я имею в виду, что различия во времени между временными метками изображений никогда не бывают одинаковыми и имеют тенденцию к увеличению в долгосрочной перспективе (первые несколько изображений почти синхронизированы, но примерно через 1 минуту каждое изображение разделяется все большим и большим количеством времени). Утечка памяти? GC?
Заранее спасибо за любую подсказку!
РЕДАКТИРОВАТЬ: В конце концов я изменил способ работы системы: я запускаю программный триггер на каждой камере, используя таймер, и каждый триггер срабатывает "параллельно":
Parallel.ForEach(Of ListOfCameras)(SingleCamera,
Sub(aCamera, loopstate, num)
aCamera.FireTrigger()
End Sub)
1 ответ
Запуск задания и его немедленная блокировка (через Wait
) ничего тебе не дает. Вы также можете просто запустить код сохраняемого изображения напрямую.
Второй пример на самом деле асинхронный. Вы, вероятно, получаете исключение, потому что ManagedImage
Аргумент или один из его дочерних объектов находится в распоряжении. Помните, что код, вызывающий событие, не знает, что ваш код асинхронный; вам нужно скопировать то, что вам нужно, из аргументов события, если вы собираетесь использовать его асинхронно.