2011-11-08 70 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

相關問題