2015-07-21 27 views
1

我正在使用VSTO並希望檢查COM對象中是否有某個屬性可用。當它可用時,它將返回一個結果,當它不可用時,它將返回一個異常。高效地檢查COM屬性是否可用,而不需要嘗試/捕獲

捕獲com異常非常緩慢,我想知道是否有更有效的方法來檢查該屬性是否會拋出異常。

注意,這個問題是相似的,但沒有一個解決方案:How to check if a COM property or method exists without generating an exception?

注意,有檢查,如果一個範圍內使用Range.SpecialCells具有驗證與否的另一種方式,但我在尋找更多檢測COM對象中的屬性是否可用的一般解決方案,因爲其他Excel COM對象出現相同的性能問題。

舉一個例子。如果範圍具有數據驗證,則Range.Validation.Type屬性將返回結果,如果它沒有數據驗證,則會引發異常。下面的代碼在有或沒有的單元上測試10次數據驗證。在我的計算機上對具有數據驗證的單元格進行測試時輸出的時間爲0毫秒,而沒有數據驗證的單元格則超過500毫秒。

public static bool HasDataValidation(Excel.Range range) 
    { 
     try 
     { 
      var validationType = range.Validation.Type; 
      return true; 
     } 
     catch (Exception) 
     { 
      return false; 
     } 
    } 

    public static void RunTest() 
    { 
     var excelApp = Globals.ThisAddIn.Application; 
     var worksheet = (Excel.Worksheet) excelApp.ActiveSheet; 
     var rangeWithoutDataValidation = worksheet.Range["A1"]; 
     var rangeWithDataValidation = worksheet.Range["A2"]; 

     rangeWithoutDataValidation.Validation.Delete(); 

     rangeWithDataValidation.Validation.Delete(); 
     rangeWithDataValidation.Validation.Add(Excel.XlDVType.xlValidateList, Excel.XlDVAlertStyle.xlValidAlertStop, 
      Excel.XlFormatConditionOperator.xlBetween, "A,B,C"); 

     var watch = Stopwatch.StartNew(); 
     for (int i = 0; i < 10; i++) 
     { 
      bool hasValidation = HasDataValidation(rangeWithoutDataValidation); 
     } 
     watch.Stop(); 
     long timeNoValidation = watch.ElapsedMilliseconds; 

     watch = Stopwatch.StartNew(); 
     for (int i = 0; i < 10; i++) 
     { 
      bool hasValidation = HasDataValidation(rangeWithDataValidation); 
     } 
     watch.Stop(); 
     long timeWithValidation = watch.ElapsedMilliseconds; 
     MessageBox.Show(String.Format("Time without validation was {0} milliseconds.\nTime with validation was {1} milliseconds.", timeNoValidation,timeWithValidation)); 
    } 
+0

您是否嘗試過在這裏漢斯的答案:http://stackoverflow.com/questions/8068449/calling-a-member-of-idispatch-com -interface-from-c-sharp –

+0

是的,我試過了,但它獲得了Type屬性的ID(對於Range.Validation對象),當它拋出異常並且拋出異常時。該屬性始終存在 – tjsmith

+0

因此,它不是檢查「屬性是否可用」的問題,而是調用屬性getter的問題。您可以嘗試立即使用IDispatch Invoke(使用DISPATCH_PROPERTYGET)。這在這裏描述:http://www.productiverage.com/idispatch-iwastedtimeonthis-but-ilearntlots –

回答

0

怎麼是這樣的:

public static bool HasDataValidation(Excel.Range range) 
{ 
    try 
    { 
     var validation = range.Validation; 
     return (validation != null); 
    } 
    catch (Exception) 
    { 
     return false; 
    } 
} 
+0

將始終返回true。就我所知,每個範圍都有一個驗證對象。如果沒有對範圍進行驗證,它是引發COM異常的Validation.Type。 – tjsmith

相關問題