2013-08-19 5 views
0

Я пишу приложение формы win32 и рисую его с помощью Direct2D. У меня есть несколько сквозных функций для анимации, и я делаю веб-запросы с помощью WinHTTP. Проблема в том, что когда я использую любые функции 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; 
} 
+0

После вашего кода немного сложно. Можете ли вы определить, что вы имеете в виду, прекратив спокойно? –

+0

Я прошу прощения за это, я много писал, потому что я только частично уверен, где проблема. Я имею в виду, что если вы закроете программу (нажав X), несмотря на то, что потоки, казалось, закончились (они не запускают точки останова в их proc), процесс продолжает работать. –

+0

Вы также можете рассмотреть, правильно ли отключены «animatetext» и «loadwheel». Ни один из этих потоков, похоже, не ждет, пока они не закончатся. Я бы подумал об использовании '_beginthreadex()', чтобы получить корректный десктопный дескриптор и 'WaitForSingleObject()' или 'WaitForMultipleObjects' в соответствующих местах вашего кода. – WhozCraig

ответ

0

Насколько я знаю, как только основной поток завершается, остальные не ждали. Таким образом, проблема, вероятно, в вашем основном потоке. Вам просто нужно прикрепить отладчик, если он еще не отлаживается (отладка | Прикрепить к процессу в VS), к процессу зомби и нажать «Разбить все», затем использовать окна «Нитки» и «Стек вызовов», чтобы понять, что происходит.

+0

Это имеет смысл, однако, я тестировал, не создавая никаких потоков, и проблема сохранялась, вызванная только вызовом любых функций WinHTTP. В Break All отображается несколько потоков, но ни один из них не создается непосредственно пользователем. –

+0

Я нашел, что вызов «exit (0);» в конце основных причин его прекращение, но я сомневаюсь, действительно ли это хорошая практика. –

+0

Из того, что вы говорите, я думаю, что у вас есть проблема в одном из глобальных деструкторов. Скопируйте стек основного потока (вы можете, например, найти его по идентификатору, вспомнив его при запуске) в процессе зомби. – Codeguard