개발관련/other

Excel interop 개체를 올바르게 정리하는 방법

Rateye 2021. 10. 14. 12:26
728x90
반응형
질문 : Excel interop 개체를 올바르게 정리하려면 어떻게해야합니까?

ApplicationClass )에서 Excel interop을 사용하고 있으며 finally 절에 다음 코드를 배치했습니다.

while (System.Runtime.InteropServices.Marshal.ReleaseComObject(excelSheet) != 0) { }
excelSheet = null;
GC.Collect();
GC.WaitForPendingFinalizers();

이런 종류의 작동하지만 Excel.exe 프로세스는 Excel을 닫은 후에도 여전히 백그라운드에 있습니다. 내 응용 프로그램을 수동으로 닫은 후에 만 릴리스됩니다.

내가 뭘 잘못하고 있거나 interop 개체를 올바르게 처리 할 수있는 대안이 있습니까?

답변

응용 프로그램이 여전히 COM 개체에 대한 참조를 보유하고 있기 때문에 Excel이 종료되지 않습니다.

변수에 할당하지 않고 COM 개체의 멤버를 하나 이상 호출하고 있다고 생각합니다.

나를 위해 변수에 할당하지 않고 직접 사용한 excelApp.Worksheets 개체였습니다.

Worksheet sheet = excelApp.Worksheets.Open(...);
...
Marshal.ReleaseComObject(sheet);

내부적으로 C # 이 내 코드에 의해 릴리스되지 않은 Worksheets COM 개체에 대한 래퍼를 만들었고 (내가 인식하지 못했기 때문에) Excel이 언로드되지 않은 원인이라는 것을 몰랐습니다.

이 페이지 에서 내 문제에 대한 해결책을 찾았으며 C #의 COM 개체 사용에 대한 좋은 규칙도 있습니다.

COM 개체에 두 개의 점을 사용하지 마십시오.

따라서 이러한 지식으로 위의 작업을 수행하는 올바른 방법은 다음과 같습니다.

Worksheets sheets = excelApp.Worksheets; // <-- The important part
Worksheet sheet = sheets.Open(...);
...
Marshal.ReleaseComObject(sheets);
Marshal.ReleaseComObject(sheet);

사후 모템 업데이트 :

나는 모든 독자가 Hans Passant 의이 답변을 매우주의 깊게 읽으면 나와 많은 다른 개발자가 우연히 발견 한 함정을 설명합니다. 몇 년 전에이 답변을 작성했을 때 디버거가 가비지 수집기에 미치는 영향에 대해 몰랐고 잘못된 결론을 도출했습니다. 나는 역사를 위해 내 대답을 변경하지 않고 유지하지만이 링크를 읽고 "두 점"의 길을 가지 마십시오 . .NET에서 가비지 수집 이해IDisposable로 Excel Interop 개체 정리

출처 : https://stackoverflow.com/questions/158706/how-do-i-properly-clean-up-excel-interop-objects
728x90
반응형