.NET에서 COM 객체 참조를 안전하게 출시합니다
-
11-09-2019 - |
문제
나는 RCW를 안전하게 공개하는 것에 관한 그물에 대한 많은 기사를 읽었으며, 아무도 어떤 순서대로 해야하는지 정확히 동의 할 수없는 것 같습니다. 그래서 여러분의 의견을 요구합니다. 예를 들어, 이것을 할 수 있습니다.
object target = null;
try {
// Instantiate and use the target object.
// Assume we know what we are doing: the contents of this try block
// do in fact represent the entire desired lifetime of the COM object,
// and we are releasing all RCWs in reverse order of acquisition.
} finally {
if(target != null) {
Marshal.FinalReleaseComObject(target);
target = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
그러나 어떤 사람들은 전에 쓰레기 수집을하는 것을 옹호합니다. Marshal.FinalReleaseComObject
, 일부는 후에, 그리고 일부는 전혀 그렇지 않습니다. 특히 COM 객체에서 이미 분리 된 후 모든 단일 RCW를 수동으로 GC해야합니까?
제 생각에는 RCW를 COM 객체에서 분리하고 RCW가 자연스럽게 만료되는 것이 더 간단하고 쉬울 것입니다.
object target = null;
try {
// Same content as above.
} finally {
if(target != null) {
Marshal.FinalReleaseComObject(target);
}
}
그렇게하기에 충분합니까?
해결책
Target COM 객체에 대한 참조를 제공하기 위해서는 충분합니다. 그리고 선호 그냥 전화하십시오 Marshal.FinalReleaseComObject
그리고 ~ 아니다 강제 수집. 다시 말해, 당신은 당신이 당신이 그것을 끝내 자마자 참조를 발표 할 책임을 충족했습니다. 나는 문제를 만지지 않을 것입니다 FinalReleaseComObject
vs ReleaseComObject
.
이것은 사람들이 왜 전화를 옹호하는지에 대한 더 큰 의문을 남깁니다. GC.Collect()
그리고 WaitForPendingFinalizers()
?
일부 디자인의 경우 더 이상 관리되는 참조가 없을 때 알기가 어렵 기 때문에 안전하게 전화 할 수 없습니다. ReleaseComObject
. 당신은 두 가지 선택이 있고, 메모리가 쌓이게하고 수집이 일어나거나 수집을 강요하기를 희망합니다. [의견에서 Steven Jansen의 다운 투표 메모 참조
추가 메모는 그 설정입니다 target
에게 null
일반적으로 불필요하며 구체적으로 샘플 코드에서 불필요합니다. vb6에 대한 일반적인 실습은 참조 카운트 기반 쓰레기 수집기를 사용하기 때문에 vb6에 대한 일반적인 관행입니다. C#의 컴파일러는 target
마지막 사용 후에도 도달 할 수 없으며 범위를 떠나기 전에도 GC'D를받을 수 있습니다. 그리고 마지막으로 사용하면 마지막으로 사용할 수 있으므로 설정할 수있는 경우가 있습니다. null
. 아래 코드로 직접 볼 수 있습니다.
using System;
class GCTest
{
~GCTest() { Console.WriteLine("Finalized"); }
static void Main()
{
Console.WriteLine("hello");
GCTest x = new GCTest();
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("bye");
}
}
릴리스 (예 : CSC GCTest.cs)를 구축하면 "최종"은 "Hello"와 "Bye"사이에 인쇄됩니다. 디버그 (예 : CSC /Debug GCTest.cs)를 빌드하는 경우 "최종"은 "Bye"후에 인쇄됩니다. x
이전에 null Collect()
"고정"했을 것입니다.