我编写了一个相对简单的控制台实用程序来访问ClosedXML库,以生成Excel电子表格。没有什么令人兴奋的,它应该运行得非常快。但是,当我启动它时,它会在显示任何进度之前在控制台屏幕上停留约8秒。
起初,我认为这是一个需要一段时间初始化的ClosedXML库。我点了点dotTrace并通过逐行性能分析来完成它,并得到了一些奇怪的结果:
- 主线程[14,352ms]
- 主要[99.29% - 14,251ms]
- 产生[88.88% - 12,756ms]
- 11个列出的电话,加起来为23.44%/ 4,360ms
- get_Instance [6.78% - 974ms]
- Console.ReadLine [2.75% - 394ms]
- ResolvePolicy [0.82% - 118ms]
- 11个隐藏功能[0.01% - 1ms]
- ResolvePolicy [0.20% - 29ms]
- 7个列出的电话,加起来为0.51%/ 72毫秒
- 线程“.NET SystemEvents”[3,074ms]
- ThreadStart [100% - 3,074ms]
- 运行[99.6% - 3,072ms]
- ThreadStart_Context [99.93% - 3,072ms]
现在,如果我们深入研究ThreadStart_Context
,我们会看到以下内容:
- System.Threading.ThreadHelper.ThreadStart_Context(Object)[99.93% - 3,072ms]
- Microsoft.Win32.SystemEvents.WindowThreadProc [99.90% - 3,071ms]
- Microsoft.Win32.UnsafeNativeMethods.MsgWaitForMultipleObjectsEx [87.26% - 2,682ms]
根据分析器,MsgWaitForMultipleObjectsEx
API总共被调用了26次。这意味着每次等待大约需要100毫秒。
Generate
方法是我写的,它与ClosedXML库进行了很多对话。部分操作涉及写入磁盘,但最终在控制台输出出现后完成。延迟发生在任何工作完成之前。
我的担忧是双重的:
- 为什么主线程
Generate
调用下的结果有8,396ms的时间差异?
- 为什么要拨打
MsgWaitForMultipleObjectsEx
这么多电话,共计3秒钟?我知道这可能是由于线程同步,但应用程序中只有一个线程。
醇>
更新:好的,所以我发现第二个线程实际上正在处理消息循环,因此花费的5秒钟就是没有任何窗口消息需要处理的区域。但仍然不确定8秒的差异在哪里出现。