2009-04-22 17 views
7

Win32 yerli fonksiyonları ile Marshal.ReleaseComObject nasıl kullanılır:Bu iki yerli win32 fonksiyonları ile etrafında oynuyorum

[DllImport("oleacc.dll")] 
    public static extern int AccessibleObjectFromWindow(
      IntPtr hwnd, 
      int dwObjectID, 
      ref Guid refID, 
      ref Accessibility.IAccessible ppvObject); 
    [DllImport("oleacc.dll")] 
    public static extern uint AccessibleChildren(
     Accessibility.IAccessible paccContainer, 
     int iChildStart, 
     int cChildren, 
     [Out] object[] rgvarChildren, 
     out int pcObtained); 

Ve gerektiği takdirde/Marshal aramaya gerek ben anlamakta zorlanıyorum Döndürülen nesnelerin herhangi birinde .ReleaseComOject. Minnettar olacağım, birisi bu konuda beni aydınlatabilir! Aşağıda örnek bir kullanımı var: Gerçekten yerine çalıştırmak için GC beklemeden hemen salıverilmesini uygulamak için GC almak gerekirse

Accessibility.IAccessible test(
     int hWnd, 
     string accessName) 
    { 
     Guid guidCOM = new Guid(0x618736E0, 0x3C3D, 0x11CF, 0x81, 0xC, 0x0, 0xAA, 0x0, 0x38, 0x9B, 0x71); 
     Accessibility.IAccessible a = null; 

     AccessibleObjectFromWindow(
      new IntPtr(hWnd), 
      -4, 
      ref guidCOM, 
      ref a); 
     object[] children = new object[a.accChildCount]; 
     int z; 
     AccessibleChildren(a, 0, children.Length, children, out z); 
     foreach (Accessibility.IAccessible a2 in children) 
      try 
      { 
       if (a2.get_accName(0) == accessName) 
        return a2; 
      } 
      catch 
      { 
      } 
     return null; 
    } 

cevap

6

Marshal.ReleaseComObject yararlı bir iş-başındadır. Gerçekten ihtiyacınız olmadıkça kullanmamak en iyisidir, çünkü kodunuzu üstlenme eğilimi vardır ve örtük referanslar oluşturduğunuz yerler de dahil olmak üzere her yeri uygulamak zorundasınız.

.Net'deki COM etkileşimi için en iyi yöntemin, kullandığınız yöntemlerin etrafına güçlü yazılan sarıcı sınıfları yazmak olduğundan şüpheleniyorum. Bu şekilde, örtük referanslar getirme imkanı yoktur ve kodu basitleştirir ve arayüzlerin GC için daha kolay ulaşılabilir olmasını sağlar. Bazı inek-ağacılarım bu yöntemleri kullanarak daha iyi bir hafıza davranışı olduğunu bildirdiler - nesneler, etrafta yatan gizem referanslarından ayrılmadan koşarken, zamanında serbest bırakıldı.

Genel olarak, .Net kodunda atıfta bulunulan tüm COM nesneleri, doğru COM referansını tutan bir RCW nesnesi biçiminde gerçekleştirilir - ReleaseComObject numaralı çağrı, RCW'yi referansı bir sayımla azaltacak şekilde zorlar. Bu şekilde, gerçek IUnkown örneğinde yalnızca Release aranmasına benzer. Muhtemelen yukarıda sahip olduğunuz örnekte, aramayı yapmak gerekli değildir.

+0

"Kullanmamak en iyisi", * çok özel * içeriğe bağlıdır. Örneğin bir Outlook eklentisiyle çalışırken * hemen her şey manuel olarak serbest bırakılmalıdır *. Bunu yapmamak bazı garip hatalara yol açıyor ("aşırı salıverme" aynı şeyi yapıyor, bu nedenle çok kesin sahiplik anlamlarının kodda çalışması gerekiyor). .NET'te geliştirilen Office eklentilerinde COM nesnelerini ne zaman serbest bırakacağına bakın (http://www.add-in-express.com/creating-addins-blog/2008/10/30/releasing-office-objects- ağ/). –

+0

... öte yandan [Marshal.ReleaseComObject Tehlikeli Göz önüne Alındı] (http://blogs.msdn.com/b/visualstudio/archive/2010/03/01/marshal-releasecomobject-considered-dangerous.aspx). Her şey yolunda. –

+0

Aslında, pst, VS takımının uzun soluklu hikayesi bana özel bir durum gibi görünüyor. Daha kısa bir hikaye burada alıntı yaptığınız tarafından atıfta bulunulan bu önceki blogda ele geçirilmiştir: http://blogs.msdn.com/b/cbrumme/archive/2003/04/16/51355.aspx. Marshal.ReleaseComObject kullanmak için bazı basit, kolay takip kurallarını içerir. – Cheeso