现在我有十个外围设备,都可以独立运行并获取数据,获取数据的方式是在界面上添加相应的ocx控件,设备接收到消息后会触发事件,这样我就可以进行数据处理了。
我的问题是,这样的情况是否需要多线程来处理?如果需要,如何才能让界面上的不同控件的事件由不同的线程来捕获并执行?
比如:
控件:A B C
线程:1 2 3
这样一一对应当A控件获取到消息并触发了事件时,则由1线程处理;B控件获取到消息并触发了事件时,则由2线程处理,以此类推,请问该如何处理?谢谢
我的问题是,这样的情况是否需要多线程来处理?如果需要,如何才能让界面上的不同控件的事件由不同的线程来捕获并执行?
比如:
控件:A B C
线程:1 2 3
这样一一对应当A控件获取到消息并触发了事件时,则由1线程处理;B控件获取到消息并触发了事件时,则由2线程处理,以此类推,请问该如何处理?谢谢
解决方案 »
- asp.net mvc
- 替换字符串
- 怎么安装vs2005中文团体开发版的sp1补丁,郁闷死了
- ajaxToolkit:Calendar提示 元素“Calendar”不是已知元素 错误
- 能不能让验证控件验证通过时,在页面上显示正确信息
- 在数据绑定前动态设置datagrid中控件的属性值????
- 为什么相同的操作在Dataset,Access和mssql有不同??
- 为什么点login键后,根本就没有转到login.aspx页面呢???
- ****关于IIS的:我一指定IP 192.168.0.4,就报错:文件路径"d:\wwwnet\webapplication1"与URL "http://localhost/webapplication1"不符。这
- 文本问题
- 图表的问题
- A页面的Datetime怎么在B页面获得
//自定义结构,包含了在多线程函数中的参数信息
typedef struct
{
CListCtrl *pListCtrl;
CButton *pbutton4;
CButton *pbutton5;
CButton *pbutton6;
CString strFtpSite;
CString strName;
CString strPwd;
}FTP_INFO;
CEvent g_event(FALSE,FALSE,NULL,NULL);
CString g_localpath;//本地路径
CString g_remoteFile;//远程文件
CString g_strRemotePath;//远程目录
int g_pos;//界面列表框的选中位置
UINT DownLoadFileMT(LPVOID pParam);//多线程下载文件 /********************************************************************
函数名 : DownLoadFileMT
输入参数:
pParam :FTP_INFO结构指针,包含要用的信息
输出参数:
FALSE 失败或无文件
TRUE 成功
功能描述:
多线程下载文件
全局变量: 无
调用模块:
********************************************************************/
UINT DownLoadFileMT(LPVOID pParam)
{
if(pParam==NULL)
AfxEndThread(NULL);
FTP_INFO* pInfo;
CListCtrl *lpListCtrl;
CButton *pbutton4;
CButton *pbutton5;
CButton *pbutton6;
CString strFtpSite;
CString strName;
CString strPwd;
pInfo=(FTP_INFO*)pParam;
lpListCtrl=pInfo-> pListCtrl;
pbutton4=pInfo-> pbutton4;
pbutton5=pInfo-> pbutton5;
pbutton6=pInfo-> pbutton6;
pbutton4-> EnableWindow(FALSE);
pbutton5-> EnableWindow(FALSE);
pbutton6-> EnableWindow(FALSE);
strFtpSite=pInfo-> strFtpSite;
strName=pInfo-> strName;
strPwd=pInfo-> strPwd;
CInternetSession* pSession;
CFtpConnection* pConnection;
pConnection=NULL;
pSession=new CInternetSession(AfxGetAppName(),1,PRE_CONFIG_INTERNET_ACCESS);//建立网络连接客户
try
{
pConnection=pSession-> GetFtpConnection(strFtpSite,strName,strPwd);//建立网络连接
}
catch(CInternetException* e)
{
e-> Delete();
pConnection=NULL;
return FALSE;
}
if(pConnection!=NULL)
{
pConnection-> SetCurrentDirectory((LPCTSTR)g_strRemotePath);
}
if(pConnection!=NULL)
{
if(!pConnection-> GetFile(g_remoteFile,g_localpath))//下载文件
{
pConnection-> Close();
delete pConnection;
delete pSession;
::AfxMessageBox( "文件已下载或不能下载! ");
g_event.SetEvent();
pbutton4-> EnableWindow(TRUE);
pbutton5-> EnableWindow(TRUE);
pbutton6-> EnableWindow(TRUE);
return FALSE;
}
} if(pConnection!=NULL)
{
pConnection-> Close();
delete pConnection;
}
delete pSession;
lpListCtrl-> SetItemText(g_pos,1, "Yes ");//是否下载过
SaveListFile(lpListCtrl);
pbutton4-> EnableWindow(TRUE);
pbutton5-> EnableWindow(TRUE);
pbutton6-> EnableWindow(TRUE);
g_event.SetEvent();//此处设置事件
return TRUE; } /********************************************************************
函数名 : OnDownLoad
输入参数:
无
输出参数:
无
功能描述:
根据列表框选择的文件名另开线程下载文件
全局变量: 无
调用模块:
********************************************************************/
void CFtpFileDlg::OnDownLoad()
{
// TODO: Add your control notification handler code here
if(m_pos==-1)
{
MessageBox( "请选择相应文件! ",MB_OK);
}
else
{
CString t_strFileName=m_FileList.GetItemText(m_pos,0);
CFileDialog fileDialog(FALSE, "*.* ",t_strFileName,NULL, "文件(*.*)|*.*;|| ");
if (fileDialog.DoModal() == IDOK)
{
szLocalFileName=fileDialog.GetPathName();//将文件名存入成员变量
g_localpath=szLocalFileName;
g_remoteFile=t_strFileName;
FTP_INFO* info=new FTP_INFO;
info-> strFtpSite=m_URL;
info-> strName=m_User;
info-> strPwd=m_Pass;
info-> pListCtrl=&m_FileList;
info-> pbutton4=&m_button4;
info-> pbutton5=&m_button5;
info-> pbutton6=&m_button6;
g_pos=m_pos;
g_event.ResetEvent();//将事件置为无信号状态
CWinThread* pMyThread=(CWinThread*)AfxBeginThread(DownLoadFileMT,info);
::WaitForSingleObject(g_event.m_hObject,INFINITE);
::AfxMessageBox( "下载完毕! ",MB_ICONINFORMATION);
m_lastfile= "当前播放文件: "+szLocalFileName;
UpdateData(FALSE);
}
}
} 使用时:只要加::WaitForSingleObject(g_event.m_hObject,INFINITE);
这句话,我调试线程时发现执行一点就停了(不动了)程序也死一样 怎么回事呀? 如果上面问题解决了,那下面就容易了
//批处理下载
void CFtpFileDlg::OnBatdown()
{
// TODO: Add your control notification handler code here
CString strPath;
BROWSEINFO bInfo;
LPITEMIDLIST pidl;
ZeroMemory ( (PVOID) &bInfo,sizeof (BROWSEINFO)); bInfo.hwndOwner = this-> m_hWnd;
bInfo.pszDisplayName = strPath.GetBuffer (MAX_PATH);
bInfo.lpszTitle = "要保存的目录 ";
bInfo.ulFlags = BIF_RETURNFSANCESTORS|BIF_RETURNONLYFSDIRS;
bInfo.lpfn = NULL;
bInfo.lParam = 0; if ((pidl = ::SHBrowseForFolder(&bInfo)) == NULL)
return;
char temp[MAX_PATH];
if (::SHGetPathFromIDList(pidl,temp) == FALSE)
return;
strPath.Format(temp);
for(int i=0;i <m_FileList.GetItemCount();i++)
{
CString t_strFileName=m_FileList.GetItemText(i,0);
szLocalFileName=strPath+ "\\ "+t_strFileName;//将文件名存入成员变量
g_localpath=szLocalFileName;
g_remoteFile=t_strFileName;
FTP_INFO* info=new FTP_INFO;
info-> strFtpSite=m_URL;
info-> strName=m_User;
info-> strPwd=m_Pass;
info-> pListCtrl=&m_FileList;
info-> pbutton4=&m_button4;
info-> pbutton5=&m_button5;
info-> pbutton6=&m_button6;
g_pos=i;
g_event.ResetEvent();//将事件置为无信号状态
CWinThread* pMyThread=(CWinThread*)AfxBeginThread(DownLoadFileMT,info);
::WaitForSingleObject(g_event.m_hObject,INFINITE);
}
::AfxMessageBox( "下载完毕! ",MB_ICONINFORMATION);
m_lastfile= "当前播放文件: "+szLocalFileName;
UpdateData(FALSE);
}
谢谢,我对线程不是很了解,你说的这个也是我的想法,“最关键地是,线程是“瞬间就用尽”的。比如1个小时中出现了10000次事件,即使这些事件的处理程序每一个都“使用一个单独的线程处理”,那么总的来说可能10个线程就足以并行处理这10000个程序了。这才是线程的用法。”我的目的就是用十个线程去监控十个控件的事件,不是每次事件触发都启动一个线程。我也尝试过启动子线程来创建控件,但是使用了delegate后实际上控件的创建又回到了主线程上,这样又偏离了我的想法(就完全像你第三次回复的一样)请问,怎么才能让不同的线程来监控不同的控件?
举个例子 你使用QQ 你认为你同时接收N个人的消息 就回有N个线程吗? 错 其实还是只有一个线程来监听的!
tks,现在看来这些子线程是没必要的,你说的UI停滞确实会出现,谢谢你提供解决方法,但是这里还不需要解决这个问题