6

TWAINとの通信のどの部分を、BackgroundWorkerなどの別のスレッドに入れることができますか?または:画像転送を処理するループを分割することは可能ですか?

一部のスキャナードライバーは、呼び出し元のアプリケーションに戻る前にすべての画像をスキャンします。これにより、アプリケーションはすべての画像を一度に処理します。これにより、たとえば、突然すべてのイベント(スキャンされたすべての画像の後に発生)を一度に処理する必要がある場合に、WPFアプリケーションでOutOfMemoryExceptionまたは奇妙な動作が発生します。さらに、転送が完了するまでアプリケーションがハングします。

私はTwainDotNetを使用しています:http ://code.google.com/p/twaindotnet/しかし、メッセージフィルターとTwainDotNetに依存しないTWAINとの相互作用を説明する一般的なソリューションも探しています。TWAINメッセージを含むワークフローで十分です。他の言語も歓迎されます。CやDeplhiのようなものが望ましいです。

DataSourceManagerでのメッセージフィルターの現在の実装は、次のように説明できます。

  • ウィンドウハンドル(hwnd)からメッセージ情報を取得する
  • フィルタを複雑にしたり、TWAINなどに送信したりします。
  • メッセージが閉じた場合(たとえば、TWAIN UIのキャンセルボタンを押した場合)
    • データソースを閉じる
    • フィルタを無効にする
    • ScanningCompleteイベントを呼び出す
  • メッセージ転送の準備ができている場合:
    • ループ内(ADFが空になるまでなど、これによりメッセージフィルターがブロックされます)
      • 画像を取得
      • 画像ポインタをGDI+画像に変換します
      • パラメータとして画像を使用してTransferImageイベントを呼び出します
    • 転送をリセット
    • データソースなどを閉じます(メッセージを閉じるのと同じ)
  • メッセージが処理されたことをウィンドウに通知します

私はこれをいくつかのスキャナーでテストしました:

  • 富士通fi-5120Cは、ページが転送されるたびにTransferImageイベントを呼び出します。画像は、WPFアプリケーションの画像リストにすぐに表示されます。
  • Canon DR-5010Cは、すべての画像がスキャンされるまで(ループが終了するまで)、WPFアプリケーションをブロックします。Windowsは、WPFアプリケーションが応答していないとさえ言っています。すべての画像が転送されると、少数の画像のみが表示され、画像リストでの選択がちらつきます。

表示の問題ではなく、ウィンドウのブロックとメモリの問題について心配しています。画像をBackgroundWorkerに転送するループを配置すると、いくつかのクラッシュが発生し、デバッグできませんでした。原因として、WPFのスレッドの問題を検討しました。また、転送ループを分割する方法もわかりません。そのため、1つの画像を転送した後、プログラムはメッセージフィルタに戻り、メッセージに処理済みのマークを付けることができます。

4

1 に答える 1

8

私はAtalasoftで働いていますが、WPFについても、DotTwainについてもあまり知りません。

通常、TWAINスキャンは別のスキャンスレッドで実行できますが、注意が必要です。最も簡単なアプローチは、スキャンスレッドですべてのTWAIN操作を実行することです。2つのスレッド間でTWAIN呼び出しを混在させないでください。

スキャンスレッドは、メッセージポンプを備えているか、「UI」スレッドである必要があります。単なるワーカースレッドではありません。

TWAINは、スキャナーのUIの親ウィンドウとして使用するウィンドウハンドル(旧式のWin32 HWND)が与えられることを期待しています。この目的のために、スキャンスレッドに「スキャン親」ウィンドウを作成することをお勧めします。必要に応じて表示するかどうかを指定し、スキャンジョブの最後に破棄することができます。

スキャンジョブが非常に大きくなる可能性がある場合(たとえば、400 DPIカラーの50ページ)、スキャンプロセスが論理メモリまたはRAMのいずれかをいっぱいにしないことを確認する必要があります。論理メモリがいっぱいになると(32ビットのWindowsプロセスは約2GBのアドレス空間を処理できるようになります)、割り当ては失敗します。RAMがいっぱいになると、着信イメージを消費/破棄しているコードがスワップを開始し、大幅に速度が低下し、スキャンが先に実行されて論理メモリがいっぱいになる可能性があります。したがって、次のいずれかを行う必要があります。

  1. スキャンスレッドで各受信画像を完全に処理して破棄するか、または
  2. スキャンスレッドからの画像の流れを調整して、処理/処理よりもはるかに先に実行されないようにします。

私は通常、スキャンスレッドをキャンセルできるようにしたいのですが、TWAIN呼び出しは中断できないため、ある程度の忍耐が必要であり、一部は重いものです。あなたがあなたのキヤノンで気づいたように。一方、TWAIN呼び出し内でスレッドを強制終了すると、スキャナーは電源の入れ直しまたはシステムの再起動を必要とする場合があり、TWAINマネージャーDLLがメモリーからアンロードされて再ロードされるまでTWAIN自体がブロックされます。通常、TWAINを非常に丁寧にシャットダウンするのが最善です。

于 2013-04-08T14:54:11.640 に答える