【问题标题】:Is a ComWrapper class wise to wrap a Interop Com Object包装 Interop Com 对象的 ComWrapper 类是否明智?
【发布时间】:2015-07-12 20:44:04
【问题描述】:

使用互操作通信对象的应用程序。因此,我编写了一个包装类,用于在 dispose 中进行释放,或者如果在终结器中没有这样做。所以我可以使用using 关键字来确保完成释放。

使用这种模式是个好方法吗?或者框架中是否有一个类为我做这件事?

    class ComWrapper<T> : IDisposable
    {
        private readonly T comObject;

        private bool disposed = false;

        public ComWrapper(T comObject)
        {
            this.comObject = comObject;
        }

        ~ComWrapper()
        {
            this.Dispose(false);
        }

        public T ComObject
        {
            get
            {
                return this.comObject;
            }
        }

        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        public void Dispose(bool disposing)
        {
            if (this.disposed)
            {
                return;
            }

            Marshal.FinalReleaseComObject(this.comObject);
        }
    }

【问题讨论】:

  • 你的方法很好。框架中没有类可以为您执行此操作。处理 com 对象后,您忘记将 disposed 字段设置为 true。 Dispose(bool) 应该是受保护的和虚拟的(如果可以继承的话)。
  • 不,这是根本上被破坏的代码,它只能用于非常简单的 COM 对象模型。我有点厌倦了与程序员谈论这个错误,只是read this blogpost来自那些做过很多事情的人。
  • 我有一些简单的 Com 对象用于旧系统的 API。如果发生这种情况,API 将在 .NET 中一步重写。

标签: c# interop dispose finalize


【解决方案1】:

我个人不会推荐这个,因为它似乎有点毫无意义。但是,我建议使用这种方法创建一个名为 Utility 的静态类:

    public static void disposeComObject<T>(ref T comObject)
    {
       if(Marshal.IsComObject(comObject) && comObject != null)
       {
           //You need to save the object
           if(typeof(T) == typeof(Microsoft.Office.Interop.Excel.Workbook))
           {
                ((Microsoft.Office.Interop.Excel.Workbook))comObject.Save();
                ((Microsoft.Office.Interop.Excel.Workbook))comObject.Close();
           }

           //You need to save the object
           if(typeof(T) == typeof(Microsoft.Office.Interop.Excel.Application))
           {
                ((Microsoft.Office.Interop.Excel.Application))comObject.Quit();
           }

           Marshal.ReleaseComObject(comObject);
           comObject = null;
       }
    }

现在从代码中,你可以这样调用它

     ...
     Microsoft.Office.Interop.Excel comObject = null;
     try{
        //Open comObject
        //Here I would call some functions, and have nested exceptions
     }
     catch(nestedException err)
     {
          //Handle at your discretion
     }
     finally{
          Utility.disposeComObject(ref comObject);
     }

这是特定于 Excel 命名空间的,但调整它应该很容易。

【讨论】:

    猜你喜欢
    • 2010-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-15
    • 2013-08-18
    • 1970-01-01
    • 1970-01-01
    • 2012-05-02
    相关资源
    最近更新 更多