Как я могу сканировать и передавать изображения из устройства подачи документов асинхронно - PullRequest
6 голосов
/ 15 декабря 2010

Какие части связи с TWAIN могут быть помещены в другой поток, например, BackgroundWorker? Или же: Можно ли разделить цикл, который обрабатывает передачу изображения?

Некоторые драйверы сканера сканируют все изображения перед возвратом в вызывающее приложение, которое заставляет приложение обрабатывать все изображения одновременно. Это приводит, например, к OutOfMemoryException или странное поведение в моем приложении WPF, когда внезапно все события (возникающие после каждого отсканированного изображения) должны обрабатываться одновременно. Кроме того, приложение зависает, пока передача не будет завершена.

Я использую TwainDotNet: http://code.google.com/p/twaindotnet/, но я также ищу общее решение, описывающее фильтр сообщений и взаимодействие с TWAIN независимо от TwainDotNet. Рабочий процесс, содержащий сообщения TWAIN, будет достаточным. Также приветствуются другие языки, предпочтительнее что-то вроде C или Deplhi.

Текущая реализация фильтра сообщений в DataSourceManager может быть описана следующим образом:

  • Получить информацию о сообщении из дескриптора окна (hwnd)
  • Сложный фильтр, отправка материала в TWAIN и т. Д.
  • если сообщение закрывается (например, при нажатии кнопки отмены в интерфейсе TWAIN)
    • Закрыть источник данных
    • Отключить фильтр
    • Событие вызова ScanningComplete
  • если передача сообщения готова:
    • В цикле (до тех пор, пока ADF не опустеет и т. Д., Это блокирует фильтр сообщений)
      • Получить изображение
      • Преобразование указателя изображения в GDI + изображение
      • Вызовите событие TransferImage с изображением в качестве параметра
    • Сброс передачи
    • Закрыть источник данных и т. Д. (Так же, как сообщение закрыть)
  • Уведомить windows, что сообщение обработано

Я проверил это на нескольких сканерах:

  • Fujitsu fi-5120C вызывает событие TransferImage при каждой передаче страницы. Изображение сразу же появляется в списке изображений в моем приложении WPF.
  • Canon DR-5010C блокирует мое приложение WPF до тех пор, пока не будут отсканированы все изображения (до конца цикла). Windows даже говорит, что приложение WPF не отвечает. После передачи всех изображений отображается только несколько изображений, и выбор в списке изображений мигает и т. Д.

Меня волнуют не проблемы с дисплеем, а заблокированное окно и проблемы с памятью. Помещение цикла передачи изображений в BackgroundWorker вызвало несколько сбоев, которые я не смог отладить. Конечно, я рассмотрел вопросы потоков в WPF. Я также не знаю, как разделить цикл передачи, чтобы после передачи одного изображения программа вернулась к фильтру сообщений, и сообщение можно было пометить как обработанное.

1 Ответ

8 голосов
/ 08 апреля 2013

Я работаю в Atalasoft, но я не знаю WPF или даже почти ничего о DotTwain!

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

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

TWAIN ожидает, что ему будет предоставлен дескриптор окна (старомодный Win32 HWND) для использования в качестве родительского окна для пользовательского интерфейса сканера.Для этой цели я рекомендую создать окно «родительское сканирование» в потоке сканирования.Вы можете сделать его видимым или нет по своему усмотрению и уничтожить его в конце задания на сканирование.

Если задания на сканирование могут быть очень большими (например, 50 страниц с разрешением 400 точек на дюйм), вы должны убедиться, чтопроцесс сканирования не заполняет ни логическую память, ни оперативную память.Если вы заполняете логическую память (32-битный процесс Windows получает около 2 ГБ адресного пространства для работы), выделения не будут выполнены.Если вы заполняете ОЗУ, код, который потребляет / утилизирует входящие изображения, может начать меняться, радикально замедляясь, затем сканирование выполняется и заполняется логическая память.Поэтому вам необходимо либо:

  1. полностью обработать и утилизировать каждое входящее изображение в потоке сканирования, либо
  2. уменьшить поток изображений из потока сканирования, чтобы он не мог зайти слишком далекоперед их обработкой / удалением.

Я обычно нахожу, что хочу иметь возможность отменить поток сканирования, что требует некоторого терпения, так как вызовы TWAIN не могут быть прерваны, а некоторые из них тяжелы.Как вы заметили с вашим каноном.С другой стороны, если вы принудительно уничтожите поток внутри вызова TWAIN, сканеру может потребоваться цикл питания или даже перезагрузка системы, и сам TWAIN будет блокироваться до тех пор, пока DLL-библиотека менеджера TWAIN не будет выгружена из памяти и загружена повторно.Обычно лучше всего вежливо отключить TWAIN.

...