2013-05-02 1 views
3

서버 측에서 스프레드 시트를 생성하고 매크로를 실행하는 웹 응용 프로그램이 있습니다. 그런 다음 전자 메일을 통해 다른 개인에게 보냅니다. 그것은 우리가 전환하고 있지만 IIS에서 웹 사이트로 전달한 새로운 응용 프로그램을 여전히 지원하는 기존보고 스타일의 일부입니다.Server Side Generated Excel에서 System.Runtime.InteropServices.COMException 오류 발생

Office 자동화를 지원하지 않는 Microsoft의 정보를 보았을 때 Office Automation을 수행하는 것은 나쁜 습관이라는 것을 알고 있습니다. 또한 답변에 표시되어 있습니다 opening excel error: System.Runtime.InteropServices.COMException (0x80080005): Retrieving the COM class factory for component with CLSID

어쨌든 3 ~ 300 개의 보고서를 다른 사람에게 전송할 수있는 일괄 시나리오에서 생성되는 Excel 보고서가 짧습니다. 그것이 밖으로 배변 후 20 항목으로 15 주위에 도달 할 때까지 보고서 생성은 나에게 잘못 될 일을

System.Runtime.InteropServices.COMException (0x80080005): Retrieving the COM class factory for component with CLSID {00024500-0000-0000-C000-000000000046} failed due to the following error: 80080005 Server execution failed (Exception from HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE)). 
    at System.Runtime.Remoting.RemotingServices.AllocateUninitializedObject(RuntimeType objectType) 
    at System.Runtime.Remoting.Activation.ActivationServices.CreateInstance(RuntimeType serverType) 
    at System.Runtime.Remoting.Activation.ActivationServices.IsCurrentContextOK(RuntimeType serverType, Object[] props, Boolean bNewObj) 
    at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) 
    at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache) 
    at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache) 
    at System.Activator.CreateInstance(Type type, Boolean nonPublic) 
    at Ci.Infrastructure.Reporting.ReportProviderExcel.RunReport() 

아래의 오류를 제공, 잘 작동? 첫 번째 보고서가 성공적으로 나왔습니다. 15 번째 보고서에서 20 번째 보고서가 생성되면 오류가 다시 발생합니다.

업데이트 : 문제를 확인하려고했지만 문제를 해결할 해결책이 필요합니다. 이것은 우리가 앞으로 지원을 멈추게 할 유산에 대한 것이지만 과도기에 우리는 그것이 작동 할 필요가 있음을 기억하십시오.

우리는 일련 화를 시도했지만 여전히 작동하지 않습니다. COM 예외를 쳤을 때 Excel 보고서를 생성하는 스레드를 잠자려고 시도했지만 작동하지만 우아한 결과는 아닙니다. 이 문제를 해결할 수있는 좋은 해결책은 현상금이 부여됩니다.

또 다른 업데이트 :

에이 일이 해결은 결국 MarkWalls는 말처럼

finally 
{ 
    if (dataWorksheet != null) 
    { 
     Marshal.ReleaseComObject(dataWorksheet); 
    } 

    if (worksheets != null) 
    { 
     Marshal.ReleaseComObject(worksheets); 
    } 

    if (workbook != null) 
    { 
     workbook.Close(false); 
     Marshal.ReleaseComObject(workbook); 
    } 

    if (workbooks != null) 
    { 
     workbooks.Close(); 
     Marshal.ReleaseComObject(workbooks); 
    } 

    if (excel != null) 
    { 
     excel.Quit(); 
     Marshal.ReleaseComObject(excel); 
    } 
} 

을 차단 완전히 EXCEL을 지 웁니다 작업의 단위로 엑셀 인스턴스의 각 가까운 프로세스를 다시 사용하기 전에.

+1

. "거의"효과가 있습니다.이 오류는 프로세스와 Excel.exe 프로세스간에 통신 문제가 있음을 의미합니다. 아마도 타이밍 문제, 경쟁 조건 등입니다. 한 컴퓨터에서 Excel로 보류중인 요청/COM 호출이 하나 이상 있지 않도록 Excel에 대한 모든 호출을 직렬화하는 것이 좋습니다. –

+0

두 가지 : 애플리케이션을 다시 실행하지 않고 스프레드 시트를 생성하고 삭제하는 코드를 다시 작성할 수 있습니까? 너무 많은 노력이 필요하다면 인스턴스 간 간격을 설정하여 리소스를 확보 할 시간을 확보하십시오. – RandomUs1r

답변

5

나는 이와 비슷한 문제가있었습니다. 위의 대답은 정확합니다. 서버를 꽉 채우는 가비지 수집 풀을 기본적으로 가지고 있습니다.

제 해결책은 각 Excel 인스턴스를 작업 단위로 매우 신중하게 열고 닫고 서버 프로세스에 Excel 인스턴스가 있는지 확인하는 것입니다. 그것은 단지 밤에 그것들을 하나씩 차례로 지나가고 아침에 보낼 저장소에있었습니다.

우리가 시도했지만 결국 사용하지 않아야하는 또 다른 생각은 파일을 추출하는 대신 CSV 파일을 만드는 것입니다. 데이터가 필요하면 CSV가 훨씬 더 가볍습니다. 우리는 통합 문서에 복잡한 수식을 가졌지 만 그럴 필요가 없었습니다.

+0

excatly 우리가 한 일! – Raymund

7

서버 실행이

당신은 많은 연구를 표시하지 않은

실패, 당신은 항상 이것에 대해 더 자세한 정보를 얻을 수있는 Windows 응용 프로그램 이벤트 로그에 보일 것입니다. .NET 프로그램에서 Excel을 사용하는 전형적인 문제로 어려움을 겪고 있다고 가정합니다.

이 오류 설명은 항상 정확하며 COM은 말 그대로 Excel.exe를 시작할 수 없습니다. 이것은 거의 항상 작동합니다. 왜냐하면 작동은 리소스가 부족한 상태이기 때문에 커널 메모리 풀은 일반적으로 부족합니다. 일반적으로 작업 관리자를 시작하여 (여전히 작동하는 것으로) 이유를 볼 수 있으며 프로세스 탭을 볼 수 있습니다. Excel.exe가 수십 개씩 실행되는 것을 확인할 수 있습니다. 작업 관리자를 시작할 수 없으면 응용 프로그램을 다시 시작할 때 목록에 주시하십시오.

Excel은 "많은"프로세스이며 많은 운영 체제 리소스를 사용합니다. 실제로 데스크톱 용으로 작성되었으므로 Excel.exe 인스턴스 하나만 실행됩니다. 다시 시작하더라도 두 번째 인스턴스가 시작되어 다른 인스턴스가 이미 실행 중임을 알 수 있습니다.그것은 첫 번째 사람과 이야기하고 다른 문서를 여는 것처럼 그것이 의미하는 바를하도록 요구합니다. 그리고 첫 번째 달리기 만 남기고 나간다. COM을 사용할 때 이와 동일한 메커니즘이 이 아니고이됩니다. 단지 하나의 인스턴스를 생성하고 모든 작업을 수행함으로써 당신 자신을 돌보지 않고서도.

이러한 Excel.exe 인스턴스를 사용을 중지해도 이러한 Excel.exe 인스턴스가 종료되지 않는 데는 좋은 이유가 있습니다. 프로그램에서 가비지 수집에 문제가 있습니다. 수집기가 자주 실행되지 않습니다. 이런 종류의 문제에 쉽게 빠지기 ​​때문에 일반적으로 Excel에서 모든 어려운 작업을 수행하고 가비지 수집기를 실행하기에 충분한 개체를 할당하지 않습니다.

Excel에서 문제가 발생하면 인터페이스 인스턴스가 가비지 수집 될 때만 Excel이 종료 될 수 있습니다. COM interop 시나리오에서는 메모리 관리가 매우 다르며 참조 계산됩니다. Application과 같은 인터페이스를 사용하기 시작하면 참조 카운트가 올라갑니다. 파이널 라이저가 실행되면 내려갑니다. 쓰레기 수거가 끝날 때까지는 어떤 일도 일어나지 않을 것입니다.

많은 프로그래머가 Marshal.ReleaseComObject()를 호출하여 참조 횟수를 강제로 낮추면이 문제를 해결할 수 있습니다. 그 중 많은 프로그래머들도이 문제에 곤경에 처하게됩니다. 인터페이스 참조로 호출하지 않으면 작동하지 않습니다. 프로그램에 표시되지 않는 프로그램이 있습니까?

이 작업을 수행하는 가장 좋은 방법은 Excel을 사용한 작업 후에 가비지 수집을 강제로 트리거하는 것입니다. 인터페이스 참조를 null로 설정하고 GC.Collect() + GC.WaitForPendingFinalizers()를 호출하십시오. 디버거가 연결되지 않은 상태에서 릴리스 빌드를 테스트해야합니다. Excel 인터페이스를 사용하는 방법과는 별도의 방법으로이 작업을 수행해야합니다. 작업 관리자는 당신이 앞으로 나아 갔는지 여부를 알려줍니다.

Excel을 서버에서 실행하는 것은 여전히 ​​좋지 않지만이 접근 방법이 효과가 있다면 호흡 실이 필요합니다.

+0

+1에 대한 좋은 정보는 – Raymund

+0

이 정보를 제공해 주셔서 감사합니다. –

0

당신은 보고서 생성 등의 장기 실행 프로세스 ASP.NET, MSMQ 및 Windows 서비스를 사용하여 비동기 프로그래밍을 사용하여 솔루션을 달성 할 수

웹 기반 아키텍처를 필요로 시스템 오류가 자주 발생 이유 프로세스/스레드 실행을 계속 많은 수의 보고서를 생성하는보고 기능이있는 경우

다음 기사를 보시기 바랍니다. 귀하를 위해 효과가 있기를 바랍니다.

http://www.codeproject.com/Articles/8809/How-to-do-asynchronous-programming-using-ASP-NET-M

관련 섀즈이 일반적이 지원되지 않는 이유입니다