none
在试图使用单件设计模式使用Word时出现“COM 对象与其基础 RCW 分开后就不能再使用” RRS feed

  • 问题

  • 做一个项目,其中要多次使用Inteop.Word来操作多个Word文件,大概过程是:

    Word._Application app = new Word.ApplicationClass();

    Word._Document doc = app.Documents.Open(...);

    // 处理doc

    doc.Close(...);

    app.Quit(...);

    这样是没有问题的,如果处理多个文件,因为app多次打开关闭时间会比较浪费,所以只应该做一次。然后我建了一个Singleton类,其代码如下:


        internal class WordDocumentHandler
        {
            private _Application app;

            private WordDocumentHandler()
            {
                app = new ApplicationClass();
            }
            
            ~WordDocumentHandler()
            {
                app.Quit(...);
            }

            private static WordDocumentHandler instance = new WordDocumentHandler();

            public static WordDocumentHandler GetInstance()
            {
                return instance;
            }

        }

    其中具体的处理文档代码省略了,但存在一个问题,在Finalize时那app.Quit方法会说"COM 对象与其基础 RCW 分开后就不能再使用",这样就导致winword.exe进程无法正确退出。

    希望大家多多帮助!


    Cheers, Cedric
    2010年6月7日 9:00

答案

  • 你好!

         是这样的,CLR并不保证终止器的执行顺序和时间,所以你在这里清理COM对象可能会发生问题,你尝试手动做这个工作,不再终止器里做!


    周雪峰
    2010年6月9日 10:46
    版主

全部回复

  • 你好!

         主要是你编码不当引起的,你在释放COM对象的时候,他的关联的包装对象还要使用,所以产生了这个问题,具体可以参考:

    http://hi.baidu.com/fcluser/blog/item/f4716ff37ae7795a352accb8.html


    周雪峰
    2010年6月7日 14:44
    版主
  • 首先谢谢您的答复。

    但我还想问一下您所说的“编码不当”主要指什么?

    那篇文章我之前在搜索解决方案时也看到了,虽然大体上理解,但仍然没有从中发现可以解决问题的方法。另外文章里提到图,却没有看到图。


    Cheers, Cedric
    2010年6月8日 1:31
  • 你好!

         你在类的终止器中销毁了COM对象,这时可能还有其他地方要使用!我估计问题就发生在这里!


    周雪峰
    2010年6月8日 10:23
    版主
  • 如果其它地方还要用,为什么是在destructor(Finalize)中报错呢?我到觉得是别的地方回收了这个COM对象,但这里要用时却没有了。

    不知道怎么解决。因为这个app.Quit(...)是必须要做的,不然会遗留winword.exe进程。


    Cheers, Cedric
    2010年6月9日 4:54
  • 你好!

         是这样的,CLR并不保证终止器的执行顺序和时间,所以你在这里清理COM对象可能会发生问题,你尝试手动做这个工作,不再终止器里做!


    周雪峰
    2010年6月9日 10:46
    版主
  • 好的谢谢,只能这样了,在退出程序将显示式地调用这个方法。代码很难看。
    Cheers, Cedric
    2010年6月11日 7:59