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()电话,则所有文件的顺序都是正确的。

我应该如何防止下一个打印任务在前一个打印任务完成之前开始?

我最初认为我可以使用 a lock(someObject){},直到我记得它们仅用于防止多个线程访问同一代码块。这都在同一个线程上。

我可以在Microsoft.Office.Interop.Word.Application对象 上连接一些事件DocumentOpenDocumentBeforeCloseDocumentBeforePrint

我刚刚认为这实际上可能是打印队列无法准确区分在同一秒内添加的大量文档的问题。这不可能是问题,不是吗?

附带说明一下,此循环位于从BackgroundWorker对象的 DoWork 事件调用的代码中。我正在使用它来防止 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
于 2012-12-07T13:50:03.967 回答