0

我正在编写一个 win32 表单应用程序并使用 Direct2D 绘制它。我有一些跨线程函数可以在上面做动画,我正在用 WinHTTP 做 web 请求。问题是,当我使用任何 WinHttp 函数(甚至只是打开 HINTERNET 会话)时,它会导致线程无法正确终止。在我运行一次“登录”过程后,程序无法平静退出。我已经在下面发布了相关代码:

//the login process
void __cdecl processloginasync(void* arg)
{
    //getting text from textboxes, etc.

    if(usernamestr.find(L'@') != wstring::npos && usernamestr.find(L".") != wstring::npos) {
        swapdrawmode(1);
        _beginthread(loadwheel,NULL,arg);

        void* result = NULL;
        unsigned sz = 0;
        int rescode = web_request(L"appurl.mywebsite.com/func.php",ss.str().c_str(),result,sz);
        //other code to handle the reply...
        swapdrawmode(0);
    }
    else {
        error_str = L"Invalid email address.";
        err = TRUE;
    }

    if(err == TRUE) {
        textopacity = 0;
        animatemode = 0;
        _beginthread(animatetext,NULL,arg);
    }
    //I realize I haven't called 'free' on result, I'll fix that.
}

//the web_request function
int web_request (const wchar_t* server, const wchar_t* object, void*& dest, unsigned& size)
{
    vector<void*> retval;
    vector<unsigned> szs;
    HINTERNET hSess = NULL, hConn = NULL, hReq = NULL;
    int res = 0;
    DWORD dwDownloaded = 0;
    DWORD dwSize = 0;
    DWORD retcode = NULL;
    short err = FALSE;

    const wchar_t* accepted_types[] = {
        L"image/*",
        L"text/*",
        NULL
    };

    hSess = WinHttpOpen(L"smartCARS2 Web/1.1",WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
    if(hSess)
        hConn = WinHttpConnect(hSess,server,INTERNET_DEFAULT_HTTP_PORT, NULL);
    else {
        err = TRUE;
        retcode = HTTP_OPEN_FAILED;
    }
    if(hConn)
        hReq = WinHttpOpenRequest(hConn, NULL, object, NULL, WINHTTP_NO_REFERER,accepted_types,NULL);
    else {
        err = TRUE;
        retcode = HTTP_CONN_FAILED;
    }
    if(hReq)
        res = WinHttpSendRequest(hReq, WINHTTP_NO_ADDITIONAL_HEADERS, NULL, WINHTTP_NO_REQUEST_DATA, NULL, NULL, NULL);
    else {
        err = TRUE;
        retcode = HTTP_OPENREQ_FAILED;
    }
    if(res)
        res = WinHttpReceiveResponse(hReq, NULL);
    else {
        err = TRUE;
        retcode = HTTP_SEND_REQ_FAILED;
    }

    DWORD tsize = 0;
    if(res) {
        do {
            dwSize = 0;
            if(!WinHttpQueryDataAvailable(hReq, &dwSize)) {
                retcode = HTTP_COULD_NOT_QUERY_SIZE;
                err = TRUE;
                break;
            }
            if(!dwSize)
                break;
            tsize += dwSize;
            void* rets = malloc(dwSize + 1);
            if(!rets) {
                break;
            }
            if(!WinHttpReadData(hReq, (void*)rets, dwSize,  &dwDownloaded)) {
                retcode = HTTP_COULD_NOT_READ_DATA;
                err = TRUE;
                break;
            }
            if(!dwDownloaded)  {
                retcode =  HTTP_COULD_NOT_DOWNLOAD;
                err = TRUE;
                break;
            }
            szs.push_back(dwSize);
            retval.push_back(rets);

        } while(dwSize > 0);
    }
    size = tsize;
    unsigned int sz = retval.size();
    dest = malloc(tsize);
    tsize = 0;
    for(unsigned i = 0; i < sz; i++) {
        memcpy((BYTE*)dest + tsize,retval[i],szs[i]);
        free(retval[i]);
        tsize += szs[i];
    }
    if(hSess)
        WinHttpCloseHandle(hSess);
    if(hConn)
        WinHttpCloseHandle(hConn);
    if(hReq)
        WinHttpCloseHandle(hReq);
    if(err == TRUE)
        return retcode;
    return 0;
}
4

1 回答 1

0

据我所知,一旦主线程终止,就不会等待其他线程。所以问题可能出在你的主线程中。如果尚未调试(调试 | 附加到 VS 中的进程),您只需将调试器附加到僵尸进程并按“全部中断”,然后使用“线程”和“调用堆栈”窗口来确定发生了什么。

于 2013-08-19T14:40:51.230 回答