线程未正确完成,阻止应用程序关闭

时间:2013-08-19 14:05:22

标签: c++ multithreading winapi exit winhttp

我正在编写一个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;
}

1 个答案:

答案 0 :(得分:0)

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