主要代码如下:
DWORD dwTotal = m_arrFileInfo.GetSize();
for ( int i = 0 ; i < m_arrFileInfo.GetSize() ; i++ ) 
{
pDownloadFileInfo = NULL;
pDownloadFileInfo = new DOWNLOAD_FILE_INFO;
memcpy(pDownloadFileInfo , &(m_arrFileInfo[i]),sizeof(DOWNLOAD_FILE_INFO));
DWORD dwThreadId;  if(i < MAX_EXECUTE_THREAD)
{
hThread[i] = CreateThread( 
NULL,                        // default security attributes 
0,                           // use default stack size  
ThreadFunc,                  // thread function 
pDownloadFileInfo,           // argument to thread function 
0,                           // use default creation flags 
&dwThreadId); 
hExecuteThread[i] = hThread[i];
  }
else
{
//超过MAX_EXECUTE_THREAD的线程暂时挂起
hThread[i] = CreateThread( 
NULL,                        // default security attributes 
0,                           // use default stack size  
ThreadFunc,                  // thread function 
pDownloadFileInfo,           // argument to thread function 
CREATE_SUSPENDED,                           // use default creation flags 
&dwThreadId); 
SetThreadPriority(hThread[i],THREAD_PRIORITY_IDLE);
}
} dwCount = MAX_EXECUTE_THREAD; iWant = MAX_EXECUTE_THREAD;//resume的线程的索引值是从MAX_EXECUTE_THREAD开始 BOOL bQuit = FALSE;
int iCurDown = 0;
while (!bQuit)
{
MSG msg;
int rc=0;
if(dwCount == MAX_EXECUTE_THREAD)
SetDlgItemText(IDC_STATIC_CUR_DOWN,m_arrFileInfo[0].tcFileName); rc = MsgWaitForMultipleObjects(dwCount,hExecuteThread,FALSE,INFINITE,QS_ALLEVENTS); if (rc >= WAIT_OBJECT_0 && rc < WAIT_OBJECT_0 + dwCount)
{
//得到当前通知要结束的线程
            int index = rc - WAIT_OBJECT_0;

//所有的线程都已经运行了,此时只需要控制执行中的线程了
if(iWant  == dwTotal)
{
hExecuteThread[index] = hExecuteThread[dwCount-1];
hExecuteThread[dwCount-1] = 0;
dwCount--;
}
else
{
iWant++;
hExecuteThread[index] = hThread[iWant];
::SendMessage(m_hWnd,WM_RESUME_THREAD,NULL,(LPARAM)hThread[iWant]);
} if(dwCount == 0)
{
m_prsTotalFile.SetPos(100);
bQuit = TRUE;
}

}
else if(rc == WAIT_OBJECT_0 + dwCount)
{
//窗口继续消息处理
while (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message == WM_QUIT)
{
bQuit = TRUE;
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
有时创建工作线程时,会出现,有时候创建挂起线程时,也会出现!不知道问题在哪里,我已经设置了/stack的值。

解决方案 »

  1.   

    可能是你的线程函数ThreadFunc 的问题
    把ThreadFunc 的代码贴来
    注意线程安全
      

  2.   

    MsgWaitForMultipleObjects,最多等待事件有限制好像是64。
      

  3.   

    小弟愚见,你的程序太理想化了,就是说线程函数有可能在最大化线程数出现之前已执行完毕,以至后来操作的不稳定性,我有个办法,就是利用事件的方式来监控线程的执行情况,例如:
    1.创建一个事件:CreateEvent() 来监控每个线程;
    2.把原来判断线程创建的最大数改成WaitForMultipleObjects();里面监控的参数设置为最大的线程数,在此,如有线程执行完毕,则采取相应的措施
      

  4.   

    对不住!
    DWORD WINAPI ThreadFunc( LPVOID lpParam )
    {
    DOWNLOAD_FILE_INFO* threadparam=(DOWNLOAD_FILE_INFO*)lpParam;
    char httpbuff[HTTPBUFLEN];
      TCHAR   szCause[255];
    CString strBuffer; EnterCriticalSection(&criticalSection); if(lstrlen(threadparam->tcFileName)<=0) return 1;   TRY
    {
    CInternetSession mysession;
    CStdioFile *remotefile = mysession.OpenURL(threadparam->tcDownloadUrl,1,INTERNET_FLAG_TRANSFER_BINARY|INTERNET_FLAG_RELOAD);

    CFile myfile(threadparam->tcFileName, CFile::modeCreate|CFile::modeWrite|CFile::typeBinary);
    int numbytes;
    CString strName;/*  CFileStatus fileStatus;
    CFile::GetStatus(threadparam->tcFileName, fileStatus);*/ while (numbytes = remotefile->Read(httpbuff, HTTPBUFLEN))
    myfile.Write(httpbuff, numbytes);

    myfile.Close();
    //下载成功的通知
    ::SendMessage(m_hThisWnd,WM_DOWNLOAD_STEP,NULL,(LPARAM)threadparam);

    if(threadparam) 
    {
    delete threadparam;
    threadparam = NULL;
    OutputDebugString(_T("Delete successful!"));
    }
    }
    CATCH_ALL(error)
    {
    LeaveCriticalSection(&criticalSection);
    error->GetErrorMessage(szCause,254,NULL);
    }
    END_CATCH_ALL;
    LeaveCriticalSection(&criticalSection);
    return 0;
    }const int BASE_LEN = 128;
    const int MAX_EXECUTE_THREAD = 10;
    const int K_SIZE = 1024;
    const int HTTPBUFLEN = BASE_LEN*K_SIZE*10;typedef struct  {
    TCHAR tcFileName[2*BASE_LEN];
    TCHAR tcDownloadUrl[2*BASE_LEN];
    }DOWNLOAD_FILE_INFO;
      

  5.   

    to :
    wzbhbb() MsgWaitForMultipleObjects 比WaitForMultipleObjects()更合理!
    倒是可以试试监视每个线程!
    谢谢!
      

  6.   

    试着在创建线程关键段进行异常捕获,看有没可能是结构异常(例如:除0或浮点异常?)或c++异常.
    GetExceptionCode
      

  7.   

    使用_beginthread()创建线程试试
      

  8.   

    HTTPBUFLEN有多大?
    hThread[i] = CreateThread(
    NULL, // default security attributes
    4096, //《-------用这个试试看?要比httpbuff和szCause加起来都要大
    ThreadFunc, // thread function
    pDownloadFileInfo, // argument to thread function
    0, // use default creation flags
    &dwThreadId);
    hExecuteThread[i] = hThread[i];
    }
      

  9.   

    问题解决了!
    是在linker中设置的/STACK设置错了,改为CreateThread中设置就对了!