【问题标题】:MFC C++ application is stuck in ProcessShellCommand (CMFCRibbonBar::RecalcLayout)MFC C++ 应用程序卡在 ProcessShellCommand (CMFCRibbonBar::RecalcLayout)
【发布时间】:2018-08-27 23:39:33
【问题描述】:

我有一个 C++ MFC SDI 应用程序 (MGen),它显示在 Windows 10 上启动和显示 GUI 之间有 10-20 秒的暂停。我使用 MSVS2017 性能分析器(CPU 使用)来查找在发布中占用 CPU 时间的函数建造。此暂停在ProcessShellCommand 运行中,特别是在CMFCRibbonBar::RecalcLayoutCMFCRibbonBar::LoadFromResourceCDockingManager::EnableAutoHidePanes 中。

当某些程序关闭时,暂停似乎会被删除或减少。首先,我注意到关闭 Windows 任务管理器修复了暂停并再次启动它会返回暂停。然后我发现即使没有任务管理器也会发生暂停。关闭 Chrome 有助于将暂停时间减少到 2-3 秒。

我也发现空项目如果是MSVS2017中的MFC向导创建的也存在这个问题。

我试过了:

  • 重建解决方案 - 没有帮助
  • 所有发布和调试版本(x86 和 x64)都有这个问题
  • 在 MSVS 之外运行,在不同的 PC 上运行(Windows 10 也是)- 没有帮助
  • 重新启动 Windows 似乎可以暂时解决此问题(暂停消失)。
  • 我在 CMainFrame::OnCreate() 中注释掉了 OnApplicationLook() 调用。暂停仍然存在,因为这些函数现在是从其他地方调用的:Image1Image2

代码可以在GitHub找到:

    BOOL CMGenApp::InitInstance()
    {
        // InitCommonControlsEx() is required on Windows XP if an application
        // manifest specifies use of ComCtl32.dll version 6 or later to enable
        // visual styles.  Otherwise, any window creation will fail.
        INITCOMMONCONTROLSEX InitCtrls;
        InitCtrls.dwSize = sizeof(InitCtrls);
        // Set this to include all the common control classes you want to use
        // in your application.
        InitCtrls.dwICC = ICC_WIN95_CLASSES;
        InitCommonControlsEx(&InitCtrls);

        CWinAppEx::InitInstance();

        // Initialize OLE libraries
        if (!AfxOleInit())
        {
            AfxMessageBox(IDP_OLE_INIT_FAILED);
            return FALSE;
        }

        AfxEnableControlContainer();

        EnableTaskbarInteraction(FALSE);

        // Initialize GDI+
        Gdiplus::GdiplusStartupInput gdiplusStartupInput;
        Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);

        SetRegistryKey(_T("MGen"));
        LoadStdProfileSettings(10);  // Load standard INI file options (including MRU)

        InitContextMenuManager();

        InitKeyboardManager();

        InitTooltipManager();
        CMFCToolTipInfo ttParams;
        ttParams.m_bVislManagerTheme = TRUE;
        theApp.GetTooltipManager()->SetTooltipParams(AFX_TOOLTIP_TYPE_ALL,
            RUNTIME_CLASS(CMFCToolTipCtrl), &ttParams);

        // Register the application's document templates.  Document templates
        //  serve as the connection between documents, frame windows and views
        CSingleDocTemplate* pDocTemplate;
        pDocTemplate = new CSingleDocTemplate(
            IDR_MAINFRAME,
            RUNTIME_CLASS(CMGenDoc),
            RUNTIME_CLASS(CMainFrame),       // main SDI frame window
            RUNTIME_CLASS(CMGenView));
        AddDocTemplate(pDocTemplate);

        // Parse command line for standard shell commands, DDE, file open
        CCommandLineInfo cmdInfo;

        // Enable DDE Execute open
        EnableShellOpen();

        // Dispatch commands specified on the command line.  Will return FALSE if
        // app was launched with /RegServer, /Register, /Unregserver or /Unregister.
        if (!ProcessShellCommand(cmdInfo))
            return FALSE;

        // The one and only window has been initialized, so show and update it
        m_pMainWnd->ShowWindow(SW_SHOW);
        m_pMainWnd->UpdateWindow();
        // call DragAcceptFiles only if there's a suffix
        //  In an SDI app, this should occur after ProcessShellCommand
        // Enable drag/drop open
        m_pMainWnd->DragAcceptFiles();
        return TRUE;
    }

附:我在两台 PC 中都使用了最新的组件(Intel I7-8700K 配备 64Gb RAM 和 Intel I7-4770K 配备 32Gb RAM、SSD)并且没有遇到性能问题。在应用程序启动暂停期间,CPU 仅由应用程序使用。

详细的性能分析器结果:

更详细的分析:

ExitInstance 也有同样的问题:

【问题讨论】:

  • 嗯,那些需要这么长时间的函数里面有什么?他们是否可能从远程位置获取图像?进行繁重的计算?由于重新启动似乎暂时有帮助,是否还涉及其他应用程序?你能通过反复做这件事来恶化问题吗?
  • 感谢您的回复!我将尝试获取那些 MFC 源并检查那里发生了什么。它们是标准的,我没有覆盖它们。这对我来说似乎很奇怪,因为从 ProcessShellCommand 开始没有我的代码。
  • 请看,我添加了两个屏幕截图,显示了这些函数内部发生的情况。他们不获取远程图像(仅限本地)。据我所知,没有涉及其他应用程序。不确定我是否可以重复这样做,因为这是 MFC 框架的一部分。
  • 在 mainframe.cpp 中禁用临时 OnApplicationLook(..) 并检查此问题是否仍然存在。您可以稍后通过单击 View-Application Look 在程序中手动调用它。
  • 找到了一些关于它的信息:developercommunity.visualstudio.com/content/problem/136952/… 我还收集了其他信息并与这里的经典菜单进行了比较:github.com/rualark/MGen/issues/1990

标签: c++ windows visual-studio mfc freeze


【解决方案1】:

此问题是 Microsoft 中的一个已知问题。它已通过 Windows 更新修复。因此,要修复,您需要更新 Windows 10。

【讨论】:

    猜你喜欢
    • 2014-11-11
    • 2016-07-09
    • 2013-03-23
    • 2012-11-22
    • 2014-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多