2011-11-08 36 views
4

我有一个COM类型(使用tlbimp.exe创建)和一个包装这个对象的C#类。我想在我的C#包装器的终结器中执行一些清理。继准则here我可能会写这样的事:我可以在我的终结器中引用/使用COM对象吗?

public class MyClass : IDisposable 
{ 
    private IMyComObject comObject; 

    public MyClass() 
    { 
     comObject = new MyComObject(); 
    } 

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

    ~MyClass() 
    { 
     Dispose(false); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     // Be tollerant of partially constructed instances 
     if (comObject != null) 
     { 
      comObject.Cleanup(); 
      // Account for object being disposed twice 
      comObject = null; 
     } 
    } 

    // Other bits go here... 
} 

我知道,终结器可以按任意顺序运行,所以我不应该尝试使用它实现了一个终结的任何对象,但据我可以告诉TLBIMP生成的COM类型不实现一个终结器,所以上面应该没问题。

我还没有找到任何官方文档,所以我的问题是在终结器中引用和使用COM对象是否安全?

+0

你尝试在你的Dispose方法的开始调用GC? – Bond

+0

他们*实现了一个终结器,这就是COM对象被释放的方式。所以,不,这是不安全的。 –

+0

@HansPassant我曾经认为,但我找不到任何文档说明这一点,我也看不到反汇编中的终结器 – Justin

回答

-1

我创建了一个抽象的com包装类,从中派生出所有的com包装类。我工作得很好。我的原始代码是VB,因为我需要后期绑定。我的应用程序的其余部分是用C#编写的。

public abstract class ComWrapper : IDisposable 
{ 
    protected internal object _comObject; 
    protected ComWrapper(object comObject) 
    { 
     _comObject = comObject; 
    } 

    #region " IDisposable Support " 

    private bool _disposed = false; 

    protected virtual void FreeManagedObjects() 
    { 
    } 

    protected virtual void FreeUnmanagedObjects() 
    { 
     ReleaseComObject(_comObject); 
    } 

    private void Dispose(bool disposing) 
    { 
     if (!_disposed) { 
      if (disposing) { 
       FreeManagedObjects(); 
      } 
      FreeUnmanagedObjects(); 
      _disposed = true; 
     } 
    } 

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

    protected override void Finalize() 
    { 
     Dispose(false); 
     base.Finalize(); 
    } 

    #endregion 
} 

public static class Helpers 
{ 
    public static void ReleaseComObject(ref object o) 
    { 
     if ((o != null)) { 
      try { 
       Marshal.ReleaseComObject(o); 
      } catch { 
      } finally { 
       o = null; 
      } 
     } 
    } 

    public static string ToDotNetString(object comString) 
    { 
     if (comString == null) { 
      return string.Empty; 
     } 
     string s = comString.ToString(); 
     ReleaseComObject(ref comString); 
     return s; 
    } 
} 
+0

这并没有真正回答我的问题(或编译) – Justin

相关问题