2009-04-22 1 views
7

에서 Win32 기본 기능 Marshal.ReleaseComObject를 사용하는 방법 :나는이 두 가지 기본 Win32 함수와 장난 해요

[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); 

을 내가해야하는 경우/원수를 호출 할 필요가 내가 알아내는 힘든 시간을 보내고있어 리턴 된 오브젝트의 .ReleaseComObject. 나는이 주제에 대해 누군가가 나를 계몽 할 수 있다는 것에 감사 할 것이다! 다음은 샘플 사용은 : 당신이 정말 대신 실행하는 GC 기다리는 즉시 석방을 적용 할 수있는 GC를 얻을 필요가있는 경우

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; 
    } 

답변

6

Marshal.ReleaseComObject 유용한 해결 방법입니다. 꼭 필요한 경우가 아니면 사용하지 않는 것이 가장 좋습니다. 코드를 사용하는 경향이 있으며 암시 적 참조를 만든 위치를 포함하여 모든 위치에 코드를 적용해야하기 때문입니다.

.Net에서 COM interop에 가장 적합한 방법은 사용중인 메서드 주위에 강력한 형식의 래퍼 클래스를 작성하는 것입니다. 이렇게하면 암시 적 참조를 도입 할 가능성이 없으며 코드를 단순화하고 인터페이스가 GC에보다 쉽게 ​​접근 할 수 있도록합니다. 내 암소를 구사하는 사람들 중 일부는이 방법을 사용하여 더 나은 기억 행동을 보였습니다. GC는 미스테리 참조를 남기지 않고 적시에 출시됩니다.

일반적으로 .Net 코드에서 참조되는 모든 COM 개체는 실제 COM 참조를 보유하는 RCW 개체 형식으로 구현됩니다. ReleaseComObject을 호출하면 RCW가 참조 횟수를 1만큼 감소시킵니다. 이런 식으로 실제 IUnkown 인스턴스에서 Release을 호출하는 것과 비슷합니다. 위의 예에서 아마 전화를 걸 필요가 없습니다.

+0

"사용하지 않는 것이 가장 좋습니다"라는 문맥은 매우 구체적입니다. 예를 들어 Outlook 추가 기능을 사용할 때 * 모든 것을 수동으로 릴리스해야합니다 *. 그렇게하지 않으면 정말 이상한 오류가 발생합니다 ("over-release"는 똑같습니다. 따라서 매우 정확한 소유권 의미론을 코드에서 해결해야합니다). .NET에서 개발 된 Office 추가 기능에서 COM 개체를 릴리스해야하는시기 (http://www.add-in-express.com/creating-addins-blog/2008/10/30/releasing-office-objects- 그물/). –

+0

... 다른 한편으로는 [Marshal.ReleaseComObject 위험한 것으로 간주] (http://blogs.msdn.com/b/visualstudio/archive/2010/03/01/marshal-releasecomobject-considered-dangerous.aspx). 그저 그저 뻔뻔 스럽습니다. –

+0

사실, pst, VS 팀의 오랜 바람이 나는 이야기가 특별한 경우 인 것처럼 보입니다. 더 짧은 이야기는 당신이 인용 한이 블로그 게시물에 담겨 있습니다 : http://blogs.msdn.com/b/cbrumme/archive/2003/04/16/51355.aspx. Marshal.ReleaseComObject를 사용하기위한 규칙을 따르기 쉽고 간단합니다. – Cheeso

관련 문제