请高手看一下以下线程代码是否正确,还有就是我要怎样在OnClose()中退出没有执行完的线程。
UINT CUpdateDlg::DownloadThread(void *pArg)
{
CUpdateDlg *pMainWnd = (CUpdateDlg *)pArg;
CHttpSocket HttpSocket;
CString strServer,strObject;
unsigned short nPort;
DWORD dwServiceType;
long nLength;
const char *pRequestHeader = NULL;
HttpSocket.Socket();
HttpSocket.Connect((LPTSTR)(LPCTSTR)"www.xxx.com");
HttpSocket.SetTimeout(20000,0);
HttpSocket.SetTimeout(20000,1);
pMainWnd->m_ctrlProgress.SetRange(0,pMainWnd->totalSize / 1024);
int nCompletedSize=0;
for (int i=1;i <=pMainWnd->m_list.GetItemCount();i++){
AfxParseURL("http://www.xxx.com/UpFile/user/"+pMainWnd->UserName+"/"+pMainWnd->SoftID+"/update/"+pMainWnd->m_list.GetItemText(i-1,0),dwServiceType,strServer,strObject,nPort);
pRequestHeader = HttpSocket.FormatRequestHeader((LPTSTR)(LPCTSTR)strServer,(LPTSTR)(LPCTSTR)strObject,nLength);
HttpSocket.SendRequest(pRequestHeader);
char szValue[30];
HttpSocket.GetField("Content-Length",szValue,30);
int nSvrState = HttpSocket.GetServerState();
int nFileSize = atoi(szValue);
int nSize = 0;
CFile DownloadFile;
DownloadFile.Open(pMainWnd->UpPath+"\\"+pMainWnd->m_list.GetItemText(i-1,0),CFile::modeCreate | CFile::modeWrite);
char pData[1024];
int nReceSize = 0;
while(nSize < nFileSize)
{
nReceSize = HttpSocket.Receive(pData,256);
if(nReceSize == 0)
{
AfxMessageBox("服务器已经关闭连接.");
break;
}
if(nReceSize == -1)
{
AfxMessageBox("接收数据超时.");
break;
}
DownloadFile.Write(pData,nReceSize);
nSize += nReceSize;
CString nPos;
nPos.Format("%d", (int)((float)nSize/(float)nFileSize*100+0.5f));
pMainWnd->m_list.SetItemText(i-1,2,nPos+"%");
nCompletedSize+=nReceSize;
pMainWnd->m_ctrlProgress.SetPos(nCompletedSize / 1024);
}
DownloadFile.Close();
}
HttpSocket.CloseSocket();
pMainWnd->GetDlgItem(IDOK)->EnableWindow(TRUE);
return 0;
}
void CUpdateDlg::OnOK()
{
// TODO: Add extra validation here
GetDlgItem(IDOK)->EnableWindow(FALSE);
UpdateData();
AfxBeginThread(DownloadThread,(void *)this);
}
UINT CUpdateDlg::DownloadThread(void *pArg)
{
CUpdateDlg *pMainWnd = (CUpdateDlg *)pArg;
CHttpSocket HttpSocket;
CString strServer,strObject;
unsigned short nPort;
DWORD dwServiceType;
long nLength;
const char *pRequestHeader = NULL;
HttpSocket.Socket();
HttpSocket.Connect((LPTSTR)(LPCTSTR)"www.xxx.com");
HttpSocket.SetTimeout(20000,0);
HttpSocket.SetTimeout(20000,1);
pMainWnd->m_ctrlProgress.SetRange(0,pMainWnd->totalSize / 1024);
int nCompletedSize=0;
for (int i=1;i <=pMainWnd->m_list.GetItemCount();i++){
AfxParseURL("http://www.xxx.com/UpFile/user/"+pMainWnd->UserName+"/"+pMainWnd->SoftID+"/update/"+pMainWnd->m_list.GetItemText(i-1,0),dwServiceType,strServer,strObject,nPort);
pRequestHeader = HttpSocket.FormatRequestHeader((LPTSTR)(LPCTSTR)strServer,(LPTSTR)(LPCTSTR)strObject,nLength);
HttpSocket.SendRequest(pRequestHeader);
char szValue[30];
HttpSocket.GetField("Content-Length",szValue,30);
int nSvrState = HttpSocket.GetServerState();
int nFileSize = atoi(szValue);
int nSize = 0;
CFile DownloadFile;
DownloadFile.Open(pMainWnd->UpPath+"\\"+pMainWnd->m_list.GetItemText(i-1,0),CFile::modeCreate | CFile::modeWrite);
char pData[1024];
int nReceSize = 0;
while(nSize < nFileSize)
{
nReceSize = HttpSocket.Receive(pData,256);
if(nReceSize == 0)
{
AfxMessageBox("服务器已经关闭连接.");
break;
}
if(nReceSize == -1)
{
AfxMessageBox("接收数据超时.");
break;
}
DownloadFile.Write(pData,nReceSize);
nSize += nReceSize;
CString nPos;
nPos.Format("%d", (int)((float)nSize/(float)nFileSize*100+0.5f));
pMainWnd->m_list.SetItemText(i-1,2,nPos+"%");
nCompletedSize+=nReceSize;
pMainWnd->m_ctrlProgress.SetPos(nCompletedSize / 1024);
}
DownloadFile.Close();
}
HttpSocket.CloseSocket();
pMainWnd->GetDlgItem(IDOK)->EnableWindow(TRUE);
return 0;
}
void CUpdateDlg::OnOK()
{
// TODO: Add extra validation here
GetDlgItem(IDOK)->EnableWindow(FALSE);
UpdateData();
AfxBeginThread(DownloadThread,(void *)this);
}
解决方案 »
- 有关于MFC中OnSize函数用到控件变量的问题
- 请问如何在SERVICE中启动一个远程桌面的用户程序
- 请问BSTR与_bstr_t在使用上有什么区别啊?怎样把_bstr_t转化为BSTR呢?
- OpenGL坐标变换问题?
- 如何使用CListView类为视图中的表添加行列,紧急!!!!!!!!
- 钩子问题,我改了十几天了,还是不行,大家给看看吧,救命!!有代码!!!
- 没什么分了,可是问题很难,对不住各位高手了。
- ATL地不支持MFC地DLL,其中Create了一个对话框,怎么处理对话框控件的响应函数??
- 编译错误!!!!!
- delete 和 delete[] 有什么区别呀?
- 我在OnEraseBkgnd对进度条上的按钮重绘,但是有时他还是是黑色
- 请教tab控件嵌套问题
建立会话机制
例如:
HANDLE hTEvent[3];
HANDE hPEvent;
hTEvent[0] = CreateEvent(NULL,FALSE,FALSE,NULL);//用于结束通知
hTEvent[1] = CreateEvent(NULL,TRUE,FALSE,NULL);//用于执行
hPEvent = CreateEvent(NULL,FALSE,FALSE,NULLL);void ThreadProc(LPVOID lpParam)
{
//初始化事件
LOOP: dwResult = WaitForMultipleObjects(3,lpEvents,FALSE,INFINTE);//注意触发顺序
switch(dwResult)
{
case WAIT_OBJECT_0:
//释放线程内资源
SetEvent(hPEvent);
return 0;
case WAIT_OBJECT_0+1:
//For Run
break;
} goto LOOP:
return -1;
}在Close Thread你需要等待hPEvent的触发已感知Thread是否正常退出
按照我的风格,0表示成功-1表示异常失败
所以你可以通过GetExitCodeThread来检查线程的结束值来判断结束状态
STILL_ACTIVE表示线程仍然存活最后异常处理自己加,根据需求加入SHE
1、主线程创建一个事件句柄
2、主线程创建子线程
3、子线程启动一个循环并不停检测事件句柄是否有信号,例如
while (true)
{
if (WAIT_OBJECT_0 == WaitForSingleObject(hEvent, 0))
break; // 有信号,则退出 // do something
}
4、主线程激活信号通知线程退出,并等待线程终止,例如
SetEvent(hEvent);
WaitForSingleObject(hThread, INFINITE);
#if defined(_DEBUG)
OutputDebugString("The thread has exited.\r\n");
#endif
如果你在Debug窗口看到了这个消息说明该线程已经结束,你需要在等待结束通知哪里下功夫查找错误原因。