source

IDisposable을 사용하여 Excel Interop 객체 정리

factcode 2023. 4. 9. 22:25
반응형

IDisposable을 사용하여 Excel Interop 객체 정리

저희 회사에서는 Excel Interop Objects를 출시하는 일반적인 방법은IDisposable다음과 같이 합니다.

Public Sub Dispose() Implements IDisposable.Dispose
    If Not bolDisposed Then
        Finalize()
        System.GC.SuppressFinalize(Me)
    End If
End Sub

Protected Overrides Sub Finalize()
    _xlApp = Nothing
    bolDisposed = True
    MyBase.Finalize()
End Sub

어디에_xlApp는 다음과 같은 방법으로 생성되었습니다.

Try
    _xlApp = CType(GetObject(, "Excel.Application"), Excel.Application)
Catch e As Exception
    _xlApp = CType(CreateObject("Excel.Application"), Excel.Application) 
End Try

그리고 클라이언트는,using-statementExcel interop 객체와 관련된 코드를 실행합니다.

우리는 두 개의 도트 규칙을 사용하는 것을 완전히 피한다.이제 (Excel) Interop Objects를 출시하는 방법을 연구하기 시작했는데, 이에 대한 거의 모든 논의(Excel interop Objects를 적절하게 정리하는 방법이나 릴리스 Excel Objects는 주로 사용하고 있습니다.Marshal.ReleaseComObject(), 그 중 어느 것도IDisposable인터페이스입니다.

질문입니다. 이 기능을 사용할 경우IDisposableexcel interop 객체를 릴리스하기 위한 interace?그렇다면 이러한 단점은 무엇입니까?

IDisposable Interace 사용 시 단점이 있습니까?

물론, 그것은 전혀 아무것도 성취하지 못한다.[ Using ]또는 [Dispose()]를 호출하는 것은 변수를 [Nothing]으로 설정하는 적절한 방법이 아닙니다.그게 네 코드가 하는 전부야

우리는 두 개의 도트 규칙을 사용하는 것을 완전히 피한다.

계속 무시해도 좋아요, 말도 안 되는 소리이고 슬픔만 불러일으키니까요.블로그 작성자의 암묵적인 주장은 그렇게 하면 프로그래머가 변수를 사용하여 xlApp의 가치를 저장해야 한다는 것입니다.문제집.따라서 나중에 releaseObject()를 호출하는 것을 잊지 않도록 해야 합니다.그러나 도트를 사용하지 않는 인터페이스 참조를 생성하는 문장은 더 많습니다.Range(x,y)와 같은 숨겨진 Range 객체 참조가 있습니다.그것들을 저장해야 하는 것은 믿을 수 없을 정도로 복잡한 코드를 만들어 낼 뿐이다.

그리고 한 가지만 간과하면 그 일을 완전히 완수하지 못할 수도 있다.디버깅은 전혀 불가능합니다.이것은 C 프로그래머가 작성해야 하는 코드입니다.또, 큰 C프로그램은 메모리를 리크해, 프로그래머는 그 리크를 찾아내는데 많은 시간을 소비합니다.가 아닙니다.물론 NET 방식에는 가비지 컬렉터가 있어 자동으로 실행할 수 있습니다.절대 틀리지 않아요.

문제는 일을 처리하는 데 조금 느리다는 것이다.매우 의도적으로.이런 종류의 코드를 제외하고는 아무도 이걸 알아채지 못해요.가비지 컬렉터가 실행되지 않고 Office 프로그램이 실행되고 있음을 알 수 있습니다.당신이 xlapp을 썼을 때 안 끊겼어요.종료(). 작업 관리자의 프로세스 탭에 계속 표시됩니다.그들이 원하는 것은 그들이 그렇게 말할 때 그만두는 것이다.

이것은 에서는 매우 가능합니다.NET, GC가 작업을 완료하도록 강제할 수 있습니다.

GC.Collect()
GC.WaitForPendingFinalizers()

쾅, 모든 Excel 객체 참조가 자동으로 공개됩니다.이러한 오브젝트 레퍼런스를 직접 저장하고 명시적으로 보안관에게 전화할 필요는 없습니다.ReleaseComObject()는 CLR이 대신합니다.또한 "2개의 도트 규칙"을 사용하거나 필요로 하지 않으며 숨겨진 인터페이스 참조를 다시 찾는 데 문제가 없습니다.


그러나 매우 중요한 것은 이 코드를 정확히 어디에 두느냐입니다.그리고 대부분의 프로그래머들은 엑셀 인터페이스를 사용한 것과 같은 방법으로 잘못된 위치에 배치하고 있습니다.괜찮지만 코드를 디버깅할 때는 작동하지 않습니다. 답변에 설명되어 있는 변덕입니다.블로그 작성자의 코드로 하는 적절한 방법은 코드를 작은 도우미 방법으로 이동하는 것입니다.DoExcel이라고 부릅니다.물건().다음과 같이 합니다.

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    DoExcelThing()
    GC.Collect()
    GC.WaitForPendingFinalizers()
    '' Excel.exe no longer running anymore at this point
End Sub

이 모든 것은 실제로는 디버깅 아티팩트에 불과하다는 점에 유의하십시오.프로그래머는 태스크 매니저를 사용하여 좀비 Excel.exe 인스턴스를 종료하는 것을 싫어합니다.디버거를 정지했을 때 프로그램이 정상적으로 종료되지 않고 가비지가 수집되지 않도록 좀비화되었습니다.이게 정상이에요.또, 어떠한 이유로 프로그램이 실가동중에 정지하는 경우도 발생합니다.코드의 버그를 제거하여 프로그램이 중단되지 않도록 전력을 다하십시오.GC는 그 이상의 도움을 필요로 하지 않는다.

좀 더 깨끗한 방법을 찾고 있다면 쿠그라를 이용할 수 있다.추가 오버헤드는 그다지 크지 않습니다(참조 항목에 포함시켜야 하는 dll은 2개뿐입니다). 암묵적인 가비지 컬렉션을 처리할 필요가 없습니다.

EXCEL32 또는 Excel.exe 프로세스를 남기지 않고 Excel 파일에서 10열씩 10 행을 읽는 데 필요한 코드입니다.저는 한 달 전에 이 호를 가지고 있었고,방법에 대한 설명서를 작성했습니다.Excel Interop을 직접 사용하는 것보다 훨씬 쉽고 깔끔합니다.

Koogra.IWorkbook workbook = Koogra.WorkbookFactory.GetExcel2007Reader("MyExcelFile.xlsx");
Net.SourceForge.Koogra.IWorksheet worksheet = workbook.Worksheets.GetWorksheetByName("Sheet1");

//This will invididually print out to the Console the columns A-J (10 columns) for rows 1-10.
for (uint rowIndex = 1; rowIndex <= 10; rowIndex++)
{
    for (uint columnIndex = 1; columnIndex <= 10; columnIndex++)
    {
        Console.WriteLine(worksheet.Rows.GetRow(rowIndex).GetCell(columnIndex).GetFormattedValue());
    }
}

언급URL : https://stackoverflow.com/questions/25134024/clean-up-excel-interop-objects-with-idisposable

반응형