【问题标题】:Wordapp not closing in Thread or Parallel processWordapp 未在线程或并行进程中关闭
【发布时间】:2015-03-04 09:09:36
【问题描述】:

下面的代码正常工作,并且在将 docx/doc 保存为 pdf 后打开和关闭 word,但是在线程或并行 for 循环中使用以下代码时,它没有,有任何想法吗?我已经提供了下面的所有代码。

这是在函数中使用时可以正常工作的代码。

     wordApp = new Microsoft.Office.Interop.Word.Application();
        Microsoft.Office.Interop.Word.Document wordDocument = wordApp.Documents.Open(sourceFile, false);
        wordDocument.ExportAsFixedFormat(destFile, WdExportFormat.wdExportFormatPDF);
        object saveOption = Microsoft.Office.Interop.Word.WdSaveOptions.wdDoNotSaveChanges;
        object originalFormat = Microsoft.Office.Interop.Word.WdOriginalFormat.wdOriginalDocumentFormat;
        object routeDocument = false;


        if (wordDocument != null)
            ((_Document)wordDocument).Close(ref saveOption, ref originalFormat, ref routeDocument);

        if (wordApp != null)
            ((_Application)wordApp).Quit(ref saveOption, ref originalFormat, ref routeDocument);

        wordDocument = null;
        wordApp = null;

下面是我试图调用上面代码的 Parallel.For 代码:

   Parallel.For(1, Int32.Parse(iNrOfThreads.Text), new ParallelOptions { MaxDegreeOfParallelism = Int32.Parse(iNrOfThreads.Text) }, i =>                 
            {
                fileName = fileNameLarge + i.ToString() + ".doc";
                fileName2 = fileNameLarge + i.ToString() + ".pdf";
                string sourceFile = System.IO.Path.Combine(sourcePath, fileName);
                string destFile = System.IO.Path.Combine(targetPath, fileName2);

                GeneratePDFWithProgressWithCreate(sourceFile, destFile);

            });

下面是生成线程的for循环,我试图调用上面的代码:

    for (int i = 1; i <= Int32.Parse(iNrOfThreads.Text); i++)
            {
                //fileName2 = fileNameSmall + i.ToString() + ".docx";
                fileName = fileNameLarge + i.ToString() + ".doc";
                fileName2 = fileNameLarge + i.ToString() + ".pdf";
                string sourceFile = System.IO.Path.Combine(sourcePath, fileName);
                string destFile = System.IO.Path.Combine(targetPath, fileName2);

                // To copy a file to another location and 
                // overwrite the destination file if it already exists.
                //System.IO.File.Copy(sourceFile, destFile, true);

                //Thread thread = new Thread(() => GeneratePDFWithProgress(sourceFile, destFile + ".pdf"));
                Thread thread = new Thread(() => GeneratePDFWithProgressWithCreate(sourceFile, destFile));
                thread.Name = "Thread" + i.ToString();
                thread.IsBackground = true;
                thread.SetApartmentState(ApartmentState.MTA);
                thread.Start();              
            } 

【问题讨论】:

  • 这可能是“设计使然”。 IE。我有一个模糊的回忆,Office 应用程序自动化仅在仅打开一个文档时才会有意关闭应用程序实例。当您打开多个文档实例时,然后关闭自动化对象(您在此处未能执行此操作,但由于 GC 和对象的终结器最终应该会发生)实际上不会关闭应用程序。由于没有找到 Process 实例本身并明确关闭它,我不知道有什么办法可以绕过这个设计。

标签: c# multithreading


【解决方案1】:

我通过声明变量 local 解决了这个问题

来自原始代码

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

我改成

    Microsoft.Office.Interop.Word.Application wordAppPrivate = new Microsoft.Office.Interop.Word.Application();

所以现在它是函数的本地代码,这里是使用我创建的线程调用的函数的完整代码

    void GeneratePDFWithProgressWithCreate(string wordFilename, string pdfFilename)        
    {       
            // Update Progress bar to see start of threads         
            UpdateProgress();
            // Setup Word Application
            Microsoft.Office.Interop.Word.Application wordAppPrivate = new Microsoft.Office.Interop.Word.Application();
            Microsoft.Office.Interop.Word.Document wordDocument = wordAppPrivate.Documents.Open(wordFilename, false);
            wordDocument.ExportAsFixedFormat(pdfFilename, WdExportFormat.wdExportFormatPDF);
            object saveOption = Microsoft.Office.Interop.Word.WdSaveOptions.wdDoNotSaveChanges;
            object originalFormat = Microsoft.Office.Interop.Word.WdOriginalFormat.wdOriginalDocumentFormat;
            object routeDocument = false;

            if (wordDocument != null) 
                ((_Document)wordDocument).Close(ref saveOption, ref originalFormat, ref routeDocument);
            if (wordAppPrivate != null)
                ((_Application)wordAppPrivate).Quit(ref saveOption, ref originalFormat, ref routeDocument);

            if (wordDocument != null)
                System.Runtime.InteropServices.Marshal.ReleaseComObject(wordDocument);

            if (wordAppPrivate != null)
                System.Runtime.InteropServices.Marshal.ReleaseComObject(wordAppPrivate);

            wordDocument = null;
            wordAppPrivate = null;
            //GC.Collect(); // force final cleanup!

            // Update progress bar to see finishing the conversion
            UpdateProgress();               
        //}
    }

希望对遇到类似问题的人有所帮助!

【讨论】:

  • 发生这种情况是因为并行使用了同一个变量 wordApp,因为它被声明为全局。我很高兴你修好了。我认为您可以将您的答案标记为已接受,以便让其他用户了解解决方案。
猜你喜欢
  • 2014-05-25
  • 1970-01-01
  • 1970-01-01
  • 2016-05-28
  • 2017-01-21
  • 2014-08-26
  • 1970-01-01
  • 2010-10-04
  • 2019-04-02
相关资源
最近更新 更多