如何调试缓慢的Office应用程序Interop构造函数?

10

我有一个处理Excel的应用程序。最近遇到了创建Excel对象非常缓慢的问题。

我使用以下简单代码重新创建了这个问题:

Microsoft.Office.Interop.Excel.Application xlApp;
xlApp = new Microsoft.Office.Interop.Excel.Application(); 

第二行代码导致延迟。

为了衡量新对象分配所需的时间,上述代码已经扩展了时间跟踪解决方案,并得出了结论。在正常情况下,上述代码执行需要0.5秒,而在错误行为的情况下,可能需要长达5分钟。

没有内存泄漏并且Excel对象被正确释放。我的解决方案已经全年24/7地运行,没有任何问题。我不确定是否重要,但应用程序正在20个独立用户会话(服务器机器)上运行。因此,同时会有20个此应用程序的副本运行,可能会导致同时运行20个Excel。

这个问题是2个月前第一次被注意到,并通过升级Office(2010→2013)解决了。这次我有更多时间进行调查,但结果令人失望。

事实:

  • 只有一台机器目前受到这个问题的影响(24个CPU核心,24GB的RAM)
  • “延迟”发生时,CPU根本没有压力
  • 我尝试使用“进程监视器”应用程序来验证我们“new Excel.Application()”构造函数时发生了什么(以查看是否存在过度的磁盘/内存/CPU使用)-没有资源限制的迹象。没有与COM对象相关的日志文件等
  • 这里唯一的问题就是这几分钟的延迟。所有其他Excel Interop命令都像往常一样工作。

主要问题:

  • 是否有办法调试此Microsoft.Office.Interop.Excel.Application()构造函数以查看此处存在的问题?

外部内容

编辑-附加测试

PowerPoint的构造函数不受影响。

ppApp = new Microsoft.Office.Interop.PowerPoint.Application();

2
据我所知,这个构造函数会启动 Excel 应用程序。你能否在这台机器上手动启动它,并查看加载需要多长时间?也许正在安装插件? - ttaaoossuuuu
我认为当Excel启动时,Interop默认禁用插件。该应用程序是在已登录用户的配置文件下运行还是在服务帐户下运行? - Allan Elder
@Taosique - Excel可以手动启动,没有延迟。 - adrian.krzysztofek
@Grumbler85 - 其中一个要求是模拟用户从Excel复制给定范围到剪贴板,然后将其粘贴到PowerPoint中。为了使它更加困难,您必须等待宏完成从Analysis Services Cubes加载数据。不幸的是,除非我能满足所有上述要求,否则我无法转向openXML。 - adrian.krzysztofek
1
好的 - 那就忘记我的评论吧,我只是想指出,至少创建可以比使用Interop更有效率地完成。 - TGlatzer
显示剩余8条评论
2个回答

9
我已经自己找到了解决方案。我会发布它,因为可能有人遇到类似的问题,这可以节省他几个小时/几天的调查时间。
我使用“进程监视器”分析了测试应用程序(基本上只有一行代码,在其中创建新的Excel应用程序),但没有显示任何重要内容。然后,我使用新启动的Excel进程进行了重复分析。它突出显示了大量读取Windows注册表的操作。
HKEY_USERS\S-1-5-21-2929665075-1795331740-364918325-1024\Software\Microsoft\Office\15.0\Excel\Resiliency\DocumentRecovery

在上述位置,我发现了成千上万个密钥。它们都是由Excel的“自动恢复”功能创建的。因为数量太多,每当启动新的Excel对象时加载它们需要大约40秒的时间。而且同时加载的会话数量还会增加10-20倍(我是否提到我的应用程序正在运行20个用户会话?)。
解决方案: 删除“弹性”注册表树即可解决问题。
为什么一开始就会有所有这些“自动恢复”条目呢?我想我没有很好地处理Excel的关闭,并且它“认为”我经常崩溃并“试图”帮助。
现在需要做的是防止它再次发生。我将仔细检查我的ExcelClose()函数。
感谢您的关注 - Adrian

这很棒,问答很好,旧的弹性注册表键 :) - Jeremy Thompson

2
我认为问题不在于这个构造函数。尝试动态创建对象:
var obj = Activator.CreateInstance(Type.GetTypeFromProgID("Excel.Application"));

然后将其转换为 Microsoft.Office.Interop.Excel.Application:

var xlApp = (Microsoft.Office.Interop.Excel.Application)obj;
MessageBox.Show(xlApp.Name);

我预计减速会转移到Activator.CreateInstance调用上。
无论如何,您可以尝试通过将以下内容放入您的app.config文件中来解决问题(更多详细信息):
<runtime>
    <generatePublisherEvidence enabled="false"/>
</runtime>

我建议确保您运行的是最新的VSTO运行时和最新的Office PIAs


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接