繁体   English   中英

MFC 使用 cURL 时无模式对话框冻结

[英]MFC modeless dialog freezes when using cURL

我有一个 MFC 应用程序,它尝试使用 cURL 获取页面。运行该应用程序时,对话框暂时没有响应。 有没有什么办法解决这一问题?

static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
    ((std::string*)userp)->append((char*)contents, size * nmemb);
    return size * nmemb;
}
    
static std::string GetPage(const char* url)
{
    CURL *curl;
    CURLcode res;
    std::string page;
    curl = curl_easy_init();
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, url);
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &page);

        res = curl_easy_perform(curl);

        curl_easy_cleanup(curl);
    }
    return page;
}

初始化实例():

    CWinApp::InitInstance();
    CEpicDlg dlg;
    m_pMainWnd = &dlg;
    dlg.Create(IDD_MAIN);
    dlg.ShowWindow(SW_SHOW);
    GetPage("http://example.com/page");
    dlg.RunModalLoop(MLF_NOIDLEMSG);

如前所述,您必须在单独的工作线程中运行 function。

CreateThread + WaitForSingleObject可能表现得像阻塞 function,具体取决于它的实现方式......

一种替代方法是运行工作线程并在 GUI 线程中继续。 工作线程完成后,使用同步对象让 GUI 线程了解状态。 或者使用PostMessage通知 GUI 线程工作线程已完成。 确保 url 字符串数据在没有同步的情况下不会同时在两个线程之间共享...

注意,使用CDialog::DoModal并在OnInitDialog中初始化数据。 您可能还想覆盖OnCancel以在退出 window 之前正确清理。

#define WM_USER1 (WM_USER + 1)
DWORD WINAPI thread_proc(LPVOID ptr)
{
    //simulate a blocking function (don't put Sleep in final code)
    Sleep(2000);
    HWND hwnd = (HWND)ptr;
    if(IsWindow(hwnd)) PostMessage(hwnd, WM_USER1, 0, 0);
    return 0;
}

class CMyDialog : public CDialog
{
public:
    CMyDialog(int id, CWnd* wnd) : CDialog(id, wnd) {}
    BOOL OnInitDialog()
    {
        CDialog::OnInitDialog();
        CreateThread(nullptr, 0, thread_proc, (LPVOID)m_hWnd, 0, nullptr);
        return TRUE;
    }
    LRESULT on_wm_user1(WPARAM, LPARAM)
    {
        MessageBox(L"finished");
        return 0;
    }
    DECLARE_MESSAGE_MAP()
};

BEGIN_MESSAGE_MAP(CMyDialog, CDialog)
    ON_MESSAGE(WM_USER1, on_wm_user1)
END_MESSAGE_MAP()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM