【问题标题】:C++ run a function in async and not block the uiC++ 以异步方式运行函数而不阻塞 ui
【发布时间】:2015-05-11 06:48:28
【问题描述】:

我有一个检查 dotnet 框架的小应用程序,如果没有安装它会安装它

现在,当应用程序启动时,我想弹出一个 gif 图像,并在后台检查框架并安装。

这里的问题是它不能有任何先决条件来运行应用程序

这是我目前所拥有的

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                  _In_opt_ HINSTANCE hPrevInstance,
                  _In_ LPWSTR lpCmdLine,
                  _In_ int nCmdShow)
{
       int exitCode = -1;
       showPic(hInstance);
       MessageBox(0L, L"Dotnet will installed", L"Alert", 0);
       auto fut = std::async(std::launch::async, DoWork, hInstance, lpCmdLine);
       fut.wait();
       exitCode = fut.get();
       return exitCode;
}

showPic()

void showPic(HINSTANCE hInstance)
{
    loadImage(hInstance);
    // create window
    wnd = createWindow(hInstance);
    SetWindowLong(wnd, GWL_STYLE, 0);
    ShowWindow(wnd, SW_SHOW);
}

loadImage(HINSTANCE hInstance)

void loadImage(HINSTANCE hInstance)
{
    imageDC = CreateCompatibleDC(NULL);
    imageBmp = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP1));
    imageBmpOld = (HBITMAP)SelectObject(imageDC, imageBmp);
}

现在这里发生的情况是,如果我不显示消息框,则图片不会加载到窗口中,并且窗口仍然进入无响应模式,我也无法使用 gif,只能使用 bmp 图像 任何帮助都会得到帮助

现在因为我等待 fut 很明显它会阻止 ui 直到它具有值,解决方法是什么

【问题讨论】:

    标签: c++ multithreading winapi


    【解决方案1】:

    这应该很简单。创建窗口,显示它,调用线程,进入主消息循环。当线程完成时,它会破坏窗口。

    struct T_data {
        HWND hWnd;
        HINSTANCE hInstance;
        LPTSTR cmdline;
        int exitCode;
    };
    
    DWORD WINAPI taking_too_long(LPVOID p) {
        Sleep(2000); //wait at least 2 seconds!
        T_data* data = reinterpret_cast<T_data*>(p);
        auto fut = std::async(std::launch::async, DoWork, data->hInstance, data->lpCmdLine);
        fut.wait();
        data->exitCode = fut.get();
        //make sure the window handles IDM_EXIT to close itself
        PostMessage(data->hWnd, WM_COMMAND, IDM_EXIT, 0);
    }
    
    int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR lpCmdLine, int) {
        T_data data;
        data.exitCode = -1;
        data.hWnd = hWnd;
        data.hInstance = hInstance;
        data.cmdline = lpCmdLine;
    
        data.hWnd = showPic(hInstance);
    
        CreateThread(NULL, 0, taking_too_long, &data, 0, NULL);
    
        MSG msg;
        while (GetMessage(&msg, NULL, 0, 0)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        return data.exitCode;
    }
    

    【讨论】:

    • 谢谢@DavidHeffernan,我改了。
    • @Barmak: CreateThread 与 std::future、std::async 和 PostMessage 结合使用的一个很好的例子。我真的很感激这个,并想问:这是不是很笼统,可以说是一个“日常生活的例子”?
    • 我很难理解为什么要在这里使用异步。
    • @David:你是对的,因为我们尤其不应该需要这种“双重”方法,无论是 CreatreThread 还是 std::async。还是不行?
    • @icbytes 两种明显的方法。使用CreateThread 并在线程中等待任务完成。或者使用 async,但使用 MsgWaitForMultipleObjects 运行消息循环以保持 UI 响应。
    猜你喜欢
    • 1970-01-01
    • 2021-05-26
    • 1970-01-01
    • 2016-02-15
    • 2015-04-20
    • 1970-01-01
    • 1970-01-01
    • 2016-06-09
    • 2017-10-13
    相关资源
    最近更新 更多