2010-12-15 49 views
6

與TWAIN通信的哪些部分可以放入另一個線程,例如,一個BackgroundWorker? 或者: 是否可以分割處理圖像傳輸的循環?如何從文檔進紙器異步掃描和傳輸圖像

某些掃描儀驅動程序在返回到調用應用程序之前掃描所有圖像,強制應用程序一次處理所有圖像。這導致例如OutOfMemoryException或怪異行爲在我的WPF應用程序中突然發生所有事件(在每個掃描圖像之後引發)必須立即處理。此外,應用程序掛起直到傳輸完成。

我正在使用TwainDotNet:http://code.google.com/p/twaindotnet/但我也在尋找一種通用的解決方案,描述消息過濾器和TWAIN與TwainDotNet無關的交互。包含TWAIN消息的工作流程就足夠了。其他語言也是受歡迎的,比如C或Deplhi。

當前實現在DataSourceManager消息過濾器可以描述如下:從窗口句柄(HWND)

  • 複雜的過濾器

    • Get消息信息,送的東西等TWAIN
    • 如果消息關閉(例如按下TWAIN UI中的取消按鈕時)
      • 關閉數據源
      • 禁用過濾器
      • 呼叫ScanningComplete事件
    • 如果消息傳送就緒:
      • 在一個循環(直至ADF爲空等,這種塊消息過濾器)
        • 獲取圖像
        • 將圖像指針轉換爲GDI +圖像
        • 調用具有圖像作爲參數
      • 復位轉印
      • 關閉數據源等TransferImage事件(同消息接近)
    • 通知窗口,該消息具有已處理

    我已經測試過這個與服務器al掃描儀:

    • 富士通fi-5120C每次頁面被傳輸時都會調用TransferImage事件。該圖像立即在我的WPF應用程序的圖像列表中彈出。
    • 佳能DR-5010C阻止我的WPF應用程序,直到掃描完所有圖像(直到循環結束)。 Windows甚至說,WPF應用程序沒有響應。所有圖像傳輸完畢後,只顯示少量圖像,圖像列表中的選擇會閃爍等。

    我不關心顯示問題,而是關注被阻塞的窗口和內存問題。將圖像傳輸到BackgroundWorker的循環導致了幾次崩潰,我無法調試。因爲我考慮了WPF的線程問題。 我也不知道如何拆分傳輸循環,以便在傳輸一個圖像後,程序返回到消息過濾器,並且消息可以標記爲已處理。

  • +0

    您是否想過要問TwaindotNet開發人員小組? [http://groups.google.com/group/twaindotnet-devs?pli=1](http://groups.google.com/group/twaindotnet-devs?pli=1) – ascarb 2011-01-25 16:49:07

    +0

    我在尋找一個通用的描述消息過濾器的解決方案以及與TWAIN獨立於TwainDotNet的交互。包含TWAIN消息的工作流程就足夠了。其他語言也是受歡迎的,比如C或Deplhi。 – 2011-01-26 10:50:05

    回答

    8

    我爲Atalasoft工作,但我不知道WPF,甚至不太瞭解DotTwain!

    我可以告訴你,通常TWAIN掃描可以在單獨的掃描線程上完成,但你必須小心。最簡單的方法是在掃描線程上執行所有TWAIN操作 - 不要在兩個線程之間混合使用TWAIN調用。

    掃描線程必須有一個消息泵或者是一個'UI'線程,無論您的環境如何。它不僅僅是一個工作者線程。

    TWAIN希望給出一個窗口句柄(老式的Win32 HWND)作爲掃描儀UI的父窗口。我建議在掃描線程上爲此創建一個'掃描父'窗口。您可以按照您的選擇使其可見或不可見,並在掃描作業結束時將其銷燬。

    如果您的掃描作業可能非常大(例如50頁的400 DPI顏色),您必須確保掃描過程不會填滿邏輯存儲器或RAM。如果填充邏輯內存(32位Windows進程獲得大約2GB的地址空間),則分配將失敗。如果你填滿內存,消耗/處理傳入圖像的代碼可能會開始交換,從根本上放慢速度,然後掃描運行並填充邏輯內存。所以,你需要:

    1. 完全處理,並在掃描 線程每個進入的圖像的處理,或
    2. 油門圖像從掃描的線程,因此 不能跑太遠的處理流程/配置。

    我通常會發現我希望能夠取消掃描線程,這需要一定的耐心,因爲TWAIN調用不會中斷,而且其中一些很重。正如你已經注意到你的佳能。另一方面,如果您在TWAIN調用中強制殺死線程,則掃描程序可能需要重新啓動電源或甚至重新啓動系統,TWAIN本身將阻塞,直到TWAIN管理器DLL從內存中卸載並重新加載。通常最好非常禮貌地關閉TWAIN。