2017-03-17 3 views
2

작업자 스레드에서 Excel Interop의 성능이 매우 저하되었습니다.작업자 스레드의 Excel Interop 성능이 느림

private object test(string sheetRange = "Sheet1!A1") 
    { 
     var targetRange = sheetRange.Split('!'); 
     if (targetRange.Length != 2) { return null; } 

     var sheetname = targetRange[0]; 
     var address = targetRange[1]; 
     var workbook = Application.ActiveWorkbook; 

     var sheet = (Excel.Worksheet)workbook.Worksheets[sheetname]; 
     var cell = sheet.Range[address]; 

     return cell.Value; 
    } 

내가 UI 스레드에서이 코드를 실행하면, 그것은 매우 빠르게 작동합니다

여기에 단지 지정된 셀의 값 (예를 들어, '! Sheet1의 A1')를 읽고 VSTO 프로젝트에서 내 코드입니다. 하지만 작업자 스레드에서 실행되면 성능이 상당히 떨어집니다 (약 x50 - x100 느림). 이 테스트 코드이기 때문에

 Thread thread = new Thread(() => 
     { 
      test(); 
     }); 
     thread.SetApartmentState(ApartmentState.STA); 
     thread.Start(); 
     thread.Join(int.MaxValue); 

Marshal.ReleaseComObject

은 perfomed되지 않습니다.

내 코드에 어떤 나쁜 점이 있습니까? 또는 작업자 스레드의 성능 문제를 피할 수있는 방법이 있습니까?

감사합니다.

답변

2

두 STA 스레드 사이의 COM 경계를 넘고 있습니다. COM은 모든 호출을 마샬링해야하므로 비용이 많이 듭니다.

에 Excel 관련 논리가 원래 Excel 개체를 소유 한 스레드와 다른 스레드가 있어야하는 경우 사용자가 마샬링을 수행해야합니다. 나는. 해당 워커 스레드에서 필요한 백그라운드 로직을 수행하십시오.하지만 Excel 객체와 상호 작용할 때 Excel 객체에 대한 호출을 수행하는 데 필요한 모든 데이터와 함께 소유 스레드로 돌아와서 호출 할 수 있도록하십시오 마샬링되는 대신 Excel COM 서버 코드로 직접 이동할 수 있습니다.

+0

마지막으로 "SynchronizationContext"를 사용하여 Excel 관련 논리를 메인 스레드에서 수행합니다. –