0

何かがこれはばかげた質問かもしれないと私に言います、そして私は実際に間違った方向から私の問題にアプローチしました、しかしここに行きます。

フォルダ内のすべてのドキュメントをループするコードがあります-各フォルダ内のこれらのドキュメントのアルファベット順が重要です。この重要性は、ドキュメントが印刷される順序にも反映されます。簡略化したバージョンは次のとおりです。

var wordApp = new Microsoft.Office.Interop.Word.Application();

foreach (var file in Directory.EnumerateFiles(folder))
      {
          fileCounter++;

          // Print file, referencing a previously instantiated word application object
          wordApp.Documents.Open(...)
          wordApp.PrintOut(...)
          wordApp.ActiveDocument.Close(...)
      }

PrintOutコードは非同期であるように思われ(そして私は間違っている可能性があります)、アプリケーションがドキュメントの順序が狂って印刷される状況に陥ることがあります。これは、ステップスルーするか、十分な長さSleep()の呼び出しを行うと、すべてのファイルの順序が正しいために確認されます。

前のタスクが終了する前に次の印刷タスクが開始されないようにするにはどうすればよいですか?

lock(someObject){}私は当初、複数のスレッドが同じコードブロックにアクセスするのを防ぐためにのみ役立つことを思い出すまで、を使用できると考えていました。これはすべて同じスレッド上にあります。

オブジェクトに接続できるイベントがいくつかありMicrosoft.Office.Interop.Word.Applicationます: DocumentOpenDocumentBeforeCloseおよび DocumentBeforePrint

これは、実際には、同じ秒内に追加された多くのドキュメントを正確に区別できない印刷キューの問題である可能性があると思いました。これが問題になることはありませんね。

ちなみに、このループは、オブジェクトのDoWorkイベントから呼び出されたコード内にありBackgroundWorkerます。これを使用して、UIのブロックを防ぎ、プロセスの進行状況をフィードバックしています。

4

2 に答える 2

1

あなたのイベント処理アプローチは良いもののようです。ループを使用する代わりに、DocumentBeforeCloseイベントにハンドラーを追加して、次のファイルを印刷し、Word に送信して続行することができます。このようなもの:

List<...> m_files = Directory.EnumerateFiles(folder);
wordApp.DocumentBeforeClose += ProcessNextDocument;

...

void ProcessNextDocument(...)
{
    File file = null;
    lock(m_files)
    {
        if (m_files.Count > 0)
        {
            file = m_files[m_files.Count - 1];
            m_files.RemoveAt(m_files.Count - 1);
        }
        else
        {
            // Done!
        }
    }

    if (file != null)
    {
        PrintDocument(file);
    }
}

void PrintDocument(File file)
{
    wordApp.Document.Open(...);
    wordApp.Document.PrintOut(...);
    wordApp.ActiveDocument.Close(...);
}
于 2012-12-05T01:01:03.753 に答える
0

Application.PrintOutの最初のパラメーターは、印刷をバックグラウンドで行うかどうかを指定します。に設定すると、false同期的に動作します。

于 2012-12-07T13:50:03.967 に答える