1

我编写了一个大型 VBA 程序,简而言之,它计算建筑物的能源需求。在这里发布很多代码,但首先它会读取每个建筑物的配置文件,然后从磁盘加载一些热负荷配置文件,然后动态计算 35040 刻钟时间内哪个产热器产生了多少热量。

在带有 Windows Defender 的 Windows 7 上,无论 Excel 版本是什么(2007、2010、2013、365 测试),它都能流畅运行。

现在,如果我在装有 Windows 10 和 Windows Defender (Excel 365) 的计算机上运行相同的代码,它的速度会慢很多(感觉是 1000 倍左右)。奇怪的是,一切都慢得多,这不是特定的程序或事件。从磁盘加载文件和配置文件需要很长时间,但计算循环中的能量需求(没有任何东西从驱动器传输到驱动器)也慢得多。GUI 根本没有刷新,整个应用程序似乎冻结了。

同时 MsMpEng.exe 处于满载状态,这表明 Windows Defender 有问题。令人惊讶的是,关闭 Windows Defender 后,一切运行良好。

现在,因为有太多的类/模块/等。很难说,可能是什么问题,我无法上传代码。但至少我有一个怀疑。每个类都有一个父属性,如 这里描述的那样实现。parent 属性在整个代码中被非常频繁地调用,因此如果 CopyMemory-API/Function 出现问题,那么极端的减速将是有意义的。

更新 1:我删除了 CopyMemory-Function 并用循环引用替换了所有父级。这不是长期的解决方案,但它解决了部分问题。当我等待足够长的时间时,计算会从某个点开始,并且速度与预期的一样快。所以这个问题通常与 API-Functions 有关,因为我在 GUI 上使用了很多,即

Public Declare PtrSafe Function GetDC Lib "user32" (ByVal hWnd As LongPtr) As LongPtr

Public Declare PtrSafe Function GetDeviceCaps Lib "Gdi32" (ByVal hDC As LongPtr, ByVal _
    nIndex As Long) As Long

Public Declare PtrSafe Function ReleaseDC Lib "user32" (ByVal hWnd As LongPtr, ByVal _
    hDC As LongPtr) As Long

Public Declare PtrSafe Function GetSystemMetrics32 Lib "user32" _
    Alias "GetSystemMetrics" (ByVal nIndex As Long) As Long

Public Declare PtrSafe Function SetWindowPos Lib "user32" _
        (ByVal hWnd As LongPtr, ByVal hWndInsertAfter As LongPtr, _
        ByVal X As Long, ByVal Y As Long, ByVal cx As Long, _
        ByVal cy As Long, ByVal wFlags As Long) As Long

Public Declare PtrSafe Function DrawMenuBar Lib "user32" (ByVal hWnd As LongPtr) As Long

Public Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" _
    (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Public Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" _
    (ByVal hWnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Any) As LongPtr

Public Declare PtrSafe Sub ReleaseCapture Lib "user32" ()

Public Declare PtrSafe Function ExtractIcon Lib "shell32.dll" Alias "ExtractIconA" _
    (ByVal hInst As LongPtr, ByVal lpszExeFileName As String, ByVal nIconIndex As Long) As LongPtr

Public Declare PtrSafe Function GetActiveWindow32 Lib "user32" Alias "GetActiveWindow" () As Integer

#If Win64 Then
    Public Declare PtrSafe Function GetWindowLongPtr Lib "user32" Alias "GetWindowLongPtrA" _
        (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
    Public Declare PtrSafe Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongPtrA" _
        (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#Else
    Private Declare PtrSafe Function GetWindowLongPtr Lib "user32" Alias "GetWindowLongA" _
        (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
    Private Declare PtrSafe Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongA" _
        (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#End If

更新 2(以某种方式解决了该主题):

程序的加载部分花了这么长时间的原因是因为我使用了JSON-Converter。事实证明,有一个类似的问题。由于我更新了模块并删除了所有其他 API-Call,所以一切运行良好且流畅。所以它肯定是由 API 调用引起的,尽管我不知道为什么没有那么多人抱怨巨大的性能问题。现在我无法以我不想的方式调整 GUI,而且我真的不知道如何正确实现父属性。

4

0 回答 0