对话框程序中有一静态的线程函数,线程函数中对对话框上的listctrl进行了操作.线程正在执行的时候点关闭按钮退出没有问题,但在线程正在执行的时候在listctrl上点几下再点关闭就会出错,在我的onclose函数中判断线程句柄如果有效就terminatethread 弹行退出.帮忙分析一下,我只想去掉那个出错对话框.(本来想在onclose里面等待线程结束,可是线程可能执行了多次.线程句柄是保存在一公共成员变量中.怎么都等不到它结束.调试的时候直到onclose函数结束都没问题,但继续单步走走到窗口过程函数里去了,在最后一步返回的时候就跳到汇编代码里了,提示this指针无效.)

解决方案 »

  1.   

    这是地址无效,不是内存越界,原因就是类对象释放之后线程又访问了它。
    最好的解决方法就是窗口关闭前通知线程主动退出,线程退出时发消息给窗口,然后窗口再销毁自己。
    另一种解决方式是不要给线程传递类对象指针,改成传递ListCtrl或者窗口句柄,线程对利用句柄来执行操作。
      

  2.   

    onclose里面等待还是必须的,等不到的原因可能是:
    1、有没有向线程发送退出指令?比如设置事件信号状态、或者设置退出标志。
    2、你的线程句柄是怎么得到的?如果是在工作线程中GetCurrentThread得到的,主线程就无法使用这个句柄。
      

  3.   

    退出前给线程一个通知吧。可以在出错时看看调试器的callstack,确认出错的线程是主线程还是那个新创建的线程。
      

  4.   

    我认为你分析应该是对的,但是线程不是操作了listctrl,还操作了对话框类的一些成员变量,调用了它的一些成员函数.
    而且线程执行的过程大概有10多秒,并不是循环的.所以好怎么通知线程退出,才不得已用了terminatethread.
    不知你可否有好的办法.
      

  5.   

    估计你鼠标对list的操作可能改变了线程里的对list的操作,你可以加个互斥变量,线程执行的时候不响应鼠标对list的操作
      

  6.   

    而且我在onclose里下了断点还没执行到这个函数就出错了是怎么回事?还没terminatethread,只是点了一下关闭按钮,关闭函数还未执行.
      

  7.   


    OnClickDevicelist(NMHDR* pNMHDR, LRESULT* pResult) 在listctrl点会调用这两个函数,我觉得这个函数有问题.
      

  8.   

    可以在OnClose中先隐藏窗口,然后等待线程结束再销毁窗口。
      

  9.   

    主要问题是不知道怎么等待线程退出有事件,等待它的句柄都没用,是不是我用错了.
    void CMydlg::OnSearch()//这个函数执行了多次.
    {
    m_hSear=CreateThread(NULL,0,SearchThread,this,0,NULL);
    }void CMydlg::OnClose()
    {
    WaitForSingleObject(m_hSear,INFINITE);
    CloseHandle(m_hSear);
    }
      

  10.   

    这样是等待线程结束,但线程中要访问主线程的窗口和控件,实际上是通过SendMessage来访问的,所以主线程必须响应消息,如果这样等待就会造成死锁。可以改成在OnClose中先ShowWindow(SW_HIDE),然后返回,另外自定义一个消息,在这个消息的响应函数中销毁窗口,线程在退出之前给窗口发这个消息。
      

  11.   

    给个参考:
    在静态线程函数里面,LPVOID不要用this指针,而是创建一个简单的结构体,结构体存一些在线程中要控制的必要的变量,如:
    class CParam
    {
        int iYourData;
        bool bRunThread;//检查线程结束
    };在对话框中保存一个该结构体的数组:vector<CParam*>vecParam;如果点击listctrl,需要创建线程,那么就new这么一个结构体出来,push到vecParam里面,再createThread(,,,(LPVOID)CParam*,)
    然后线程里面检查
    while((CParam*)lp->bRunThread)
    {
       dosth();
    }在onclose时,就将保存的vecParam里面的所有bRunThread = false(赋为false)sleep一下等待所有线程退出,
    最后关闭就好了(如果快速关闭,就直接ShowWindow(Sw_Hide),在后台退出线程就ok了供参考
    gl
      

  12.   

    这只能认为的避免这种情况的发生了,如果点击了Listctrl这时可让Onclose保持disnable的状态,直到线程执行完相应的动作,再恢复期状态,或者只要线程不直接对Listctrl操作,可将其数据本分下来让线程操作,尽早脱离与窗口的关系。