【发布时间】:2015-07-21 17:04:53
【问题描述】:
我正在使用 VSTO,并想检查某个属性是否在 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));
}
【问题讨论】:
-
你试过汉斯的回答吗:stackoverflow.com/questions/8068449/…
-
是的,我试过了,但是它在抛出异常和不抛出异常时都获得了 Type 属性的 ID(对于 Range.Validation 对象)。该属性始终存在
-
所以不是检查“属性是否可用”的问题,而是调用属性getter的问题。您现在可以尝试使用 IDispatch Invoke(使用 DISPATCH_PROPERTYGET)。此处对此进行了描述:productiverage.com/idispatch-iwastedtimeonthis-but-ilearntlots
标签: c# exception exception-handling com vsto