现在我有十个外围设备,都可以独立运行并获取数据,获取数据的方式是在界面上添加相应的ocx控件,设备接收到消息后会触发事件,这样我就可以进行数据处理了。
我的问题是,这样的情况是否需要多线程来处理?如果需要,如何才能让界面上的不同控件的事件由不同的线程来捕获并执行?
比如:
控件:A  B  C
线程:1  2  3
这样一一对应当A控件获取到消息并触发了事件时,则由1线程处理;B控件获取到消息并触发了事件时,则由2线程处理,以此类推,请问该如何处理?谢谢

解决方案 »

  1.   

    有人吗?可能我说得比较麻烦比如在winform的一个界面上有三个textbox,我希望启动三个线程来分别监听每个textbox的textchanged事件,当textbox的textchanged事件发生后由其对应的线程来做相应处理,请问这该如何实现
      

  2.   

    可以看看是否有用
    //自定义结构,包含了在多线程函数中的参数信息 
    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); 
      

  3.   

    sp1234
    谢谢,我对线程不是很了解,你说的这个也是我的想法,“最关键地是,线程是“瞬间就用尽”的。比如1个小时中出现了10000次事件,即使这些事件的处理程序每一个都“使用一个单独的线程处理”,那么总的来说可能10个线程就足以并行处理这10000个程序了。这才是线程的用法。”我的目的就是用十个线程去监控十个控件的事件,不是每次事件触发都启动一个线程。我也尝试过启动子线程来创建控件,但是使用了delegate后实际上控件的创建又回到了主线程上,这样又偏离了我的想法(就完全像你第三次回复的一样)请问,怎么才能让不同的线程来监控不同的控件?
      

  4.   

    你那样是没必要的 一个线程就组一监听所有事件  只是有些时间你需要防止UI的停滞  或者回处理比较长一段时间 在启动一个新新线程类处理
    举个例子 你使用QQ 你认为你同时接收N个人的消息 就回有N个线程吗? 错 其实还是只有一个线程来监听的!
      

  5.   

    zjx198934
    tks,现在看来这些子线程是没必要的,你说的UI停滞确实会出现,谢谢你提供解决方法,但是这里还不需要解决这个问题