仿照孙鑫老师的 聊天室程序, 套在自己的MFC程序上写了一个 子线程 程序子线程调用子线程程序,在子线程函数(处理一下数据)有一个消息响应, 消息响应函数实现和界面的交互。现在我有一点不明白的地方,子线程函数和消息响应函数之间任务如何分配, 我之前做个这种事情,子线程函数做一部分数据处理,消息响应函数做一部分数据处理,在调试的时候,貌似点击程序别的按钮,响应很慢,所以我想问问大家,是不是数据处理都应该放在子线程函数里面。而消息响应函数只负责简单的工作,负责和界面的交互?
还有貌似 这个 MFC 界面 类的public 变量不能用在子线程函数里, 但是消息响应函数可以用到, 我主要是想传递数据方便,不过 孙鑫老师讲了可以作为参数传给子线程函数,因为讲的我不是很理解,所以想问问具体是怎样的。

解决方案 »

  1.   

    线程内进行消息的通信,一般只是发送消息给界面GUI线程处理。
    线程内响应消息永远是一个不佳的选择,不知道这个老师怎么想的?
    线程的通信机制太多,唯有MSG是个垃圾选择。
      

  2.   

    /*子线程部分*/
    DISPARAM *pDisplayParam=new DISPARAM;
    pDisplayParam->totalcnt=m_edit_totalcnt;
    pDisplayParam->allintestrowtemp=allintestrow; pDisplayParam->hwnd=m_hWnd;//句柄传递,所有的与窗口有关的类,都有一个数据成员m_hWnd,
                               //m_hWnd保存了和这个类相关的窗口句柄
    hThread=CreateThread(NULL,0,DisProc,(LPVOID)pDisplayParam,0,NULL);//创建线程DWORD WINAPI CCDlg::DisProc(LPVOID lpParameter)
    {
    int totaltestcnt=((DISPARAM*)lpParameter)->totalcnt;
      int totalintestrow=((DISPARAM*)lpParameter)->allintestrowtemp;
    HWND hwnd=((DISPARAM*)lpParameter)->hwnd; int currentcnt,currentrow;
    for (currentcnt=1;currentcnt<totaltestcnt+1;currentcnt++)
    {
    for (currentrow=0;currentrow<totalintestrow;currentrow++)
    {
    ::PostMessage(hwnd,WM_DISDATA,(WPARAM)currentcnt,(LPARAM)currentrow);//调用消息
    Sleep(1000);
    }
    if (currentrow==totalintestrow)
    {
    currentrow=0;
    }
    }
    return 0;
    }void CCDlg::OnDisData(WPARAM currentcnt,LPARAM currentrow)
    { int allrowcnt = m_list_intest.GetItemCount();//获取所有的行数,新增加的添加到下面
    /*只高亮测试项目行*/
    int n;
    m_list_intest.SetItemState(currentrow,LVIS_DROPHILITED,LVIS_DROPHILITED);//高亮所以路过行测试项目
    for (n=0;n<currentrow;n++)//取消以往路过行的高亮显示,只显示当前行
    {
    UINT   nState=m_list_intest.GetItemState(n,LVIF_STATE);   
      nState&=!nState;   
      m_list_intest.SetItemState(n,nState,LVIF_STATE); 
    } CString currentcnttemp;
    currentcnttemp.Format("%d",currentcnt);
    SetDlgItemText(IDC_EDIT_CurrentCnt,currentcnttemp);
    }
    现在还只是框架部分,程序大概就是这样。 大家看看,我现在希望实现在面板上有很多测试项目,这些测试项目全部在子线程中运行,但是每当运行完一个测试项目的时候,就把该测试项目所在的行和测试次数着2个参数赋给相关的变量返回到界面上显示出来。线程内进行消息的通信,一般只是发送消息给界面GUI线程处理。
    线程内响应消息永远是一个不佳的选择,不知道这个老师怎么想的?
    线程的通信机制太多,唯有MSG是个垃圾选择。
    其实我不是很懂底层的东西, 请教了就我上面那个处理应该怎么做, 其实我这只是一个毕业设计,但是我还是想搞清楚明白。
      

  3.   

    说话不能太绝对吧,COM组件也利用线程内响应消息来实现single thread apartment
      

  4.   

    线程中发送消息到UI线程,UI线程负责处理UI控件
      

  5.   

       原理是这样?
    SetDlgItemText(IDC_EDIT_CurrentCnt,currentcnttemp);
    m_list_intest.SetItemState(currentrow,LVIS_DROPHILITED,LVIS_DROPHILITED;
    那请问我上面这2行 消息响应函数  中的代码是完成 发给UI线程,然后UI线程去处理控件 这样一个过程吗?
    谢谢了、、
      

  6.   

    windows为了说明他的东西的可用性,当然会使用。也不是说这个东西不能用,而是说不是一个好的选择,MS发明的横行windows平台的MSG机制,不是说每个地方都是个好的方法的。
      

  7.   

    在你的学习demo中不要在线程内部采用消息循环。作业线程如果需要和GUI线程交互,那么就线程可以通过发送消息给GUI线程,而不接收任何MSG。GUI线程如果需要和消息线程交互,那么可以通过事件进行。
    WaitForMultipleObject()/WaitForSingleObject()来等待GUI线程的通知。
      

  8.   

    像你的这种情况。界面收集需要的信息后启动线程,把this指针传递给线程,线程获取pThis指针后接收需要的数据,然后执行结算,结果通过消息SendMessage给界面。而不是界面发消息给线程。
      

  9.   

    你的意思是 创建一个 除 主线程和这个数据处理子线程外的 第三个线程 用于GUI处理?
    数据处理子线程和GUI处理线程 这2个线程通过WaitForSingleObject 和ReleaseMutex来同步工作?