我在程序中用CreateThread开了一个线程,用TerminateThread这个却关闭不了!就是当我的窗体消逝后,发现windows任务管理器里还存在,我怎么才可以用程序控制这个关掉他,就是全部退出!

解决方案 »

  1.   

    HANDLD hThread=CreateThread(....);
    ...
    ...
    TerminateThread(hThread,EXIT_FAILURE);
    CloseHandle(hThread);很可能是你TerminateThread中传入的线程句柄无效。
      

  2.   

    那是哪儿原因?
    我贴出来!我调试的就是这个'请将该部分数据保存为 FORM1.frm 文件 
    VERSION 5.00 
    Begin VB.Form Form1 
      Caption       =   "多线程" 
       ClientHeight    = 3195 
       ClientLeft      =   60 
       ClientTop      = 345 
       ClientWidth     = 6450 
       LinkTopic      =   "Form1" 
       ScaleHeight     = 3195 
       ScaleWidth      = 6450 
       StartUpPosition =   3  '窗口缺省 
       Begin VB.TextBox Text1 
        Height        = 270 
      Left        = 960 
          TabIndex     = 2 
      Text        = "2" 
      Top        = 2760 
       Width        = 2415 
      End 
       Begin VB.CommandButton Command2 
         Caption       =   "返回" 
        Height        = 255 
      Left        = 3480 
          TabIndex     = 1 
      Top        = 2760 
       Width        = 1455 
      End 
       Begin VB.CommandButton Command1 
         Caption       =   "Start Count" 
        Height        = 255 
      Left        = 3480 
          TabIndex     = 0 
      Top        = 240 
       Width        = 1455 
      End 
       Begin VB.Label Label1 
          AutoSize    =   -1 'True 
         Caption       =   "主线程执行结果测试:" 
        Height        = 180 
      Left        = 600 
          TabIndex     = 3 
      Top        = 2400 
       Width        = 1710 
       End 
    End 
    Attribute VB_Name = "Form1" 
    Attribute VB_GlobalNameSpace = False 
    Attribute VB_Creatable = False 
    Attribute VB_PredeclaredId = True 
    Attribute VB_Exposed = False  '下载地址:http://www.bssoft.com.cn/vbThread.rar Private Sub Command1_Click() 
    '声明了线程ID 
        Dim threadid1 As Long 
        Dim threadid2 As Long '参数一,lpThreadAttributes 线程安全属性,传递为NULL 
    '参数二,dwStackSize ,线程堆栈大小,可以为0,表示堆栈和此应用堆栈相同 
    '参数三,lpstartAddress ,执行函数地址,用AddressOf 获取 
    '参数四,lpParameter ,执行函数的参数地址,可以是一个记录或者是别的类型,用VarPtr获取参数地址(varptr为未公开函数)!! 
    '参数五,dwCreationFlags ,表示线程创建后的状态!,0表示立即运行,create_SUSPENDED表示线程挂起 
    '参数六,lpThreadID 表示分配给线程的线程号 
        Call CreateThread(Null, ByVal O&, AddressOf Module1.OutText1, VarPtr(0), ByVal 0&, threadid1) 
        Call CreateThread(Null, ByVal 0&, AddressOf Module1.OutText2, VarPtr(0), ByVal 0&, threadid2) 
        
    End Sub Private Sub Command2_Click() 
    '该事件运行于主线程! 
        Dim i As Long 
        i = CLng(Text1.Text) 
        Text1.Text = CStr(i * i)  '不要点击次数太多,LONG 类型会溢出 
    End Sub Private Sub Form_Load() 
    '保存窗体句柄全局变量,用于在form 上绘图 
        formhandle = Form1.hwnd 
    End Sub 
    ---------------------------------- 
    '请将该部分数据保存为 Module1.bas 文件 
    Attribute VB_Name = "Module1" '线程安全属性数据结构; 
    Public Type SECURITY_ATTRIBUTES 
           nLength As Long 
            lpSecurityDescriptor As Long 
            bInheritHandle As Long 
    End Type '这个是用于多线程访问临界资源同步Api的数据结构 
    Public Type CRITICAL_SECTION 
        dummy As Long 
    End Type 
    '为什么用GDI 函数绘图?原因等下再讲 
    Public Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long 
    Public Declare Function SetBkColor Lib "gdi32" (ByVal hdc As Long, ByVal crColor As Long) As Long 
    Public Declare Function TextOut Lib "gdi32" Alias "TextOutA" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal lpString As String, ByVal nCount As Long) As Long 
    Public Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Long 
    '请注意;createThread APi声明已被我修改过,修改的地方请自行参照APIView复制的内容 
    Public Declare Function CreateThread Lib "kernel32" (lpThreadAttributes As Any, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, ByVal lpParameter As Long, ByVal dwCreationFlags As Long, lpThreadId As Long) As Long 
    '这个是sleep,作用就是让两个线程绘图频率不一致,效果才明显。 
    Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) 
    Public Declare Sub EnterCriticalSection Lib "kernel32" (lpCriticalSection As CRITICAL_SECTION)  '进入临界区 
    Public Declare Sub LeaveCriticalSection Lib "kernel32" (lpCriticalSection As CRITICAL_SECTION)  '离开临界区 '几个重要的函数举例 
    'ObjPtr:返回对象实例私有域的地址。 
    'StrPtr:返回字符串第一个字的地址。 
    'VarPtr:返回变量的地址。 '全局的form的句柄! 
    Public formhandle As Long 
    '临界数据结构 
    Public sect As CRITICAL_SECTION Sub OutText1()  '过程一 
    Dim i As Long 
    Dim dc As Long 
    Dim s As String 
        dc = GetDC(formhandle) '获取窗体句柄的DC 
       For i = 1 To 100000 
            s = CStr(i) 
            Call SetBkColor(dc, &HF0F0F0)  '设置绘制区域的背景色,也起清除作用 
            Call TextOut(dc, 10, 10, s, Len(s)) '输出文本! 
            Call Sleep(40) '等待 
      Next 
        Call ReleaseDC(formhandle, dc)  '释放资源! 
       ' Call EnterCriticalSection(sect) 
       ' 上下表示该处为临界区,如果要对工程全局变量做操作,最好在该区域内 
       ' 否则线程同步过程中,非常容易让程序崩溃 
       ' Call LeaveCriticalSection(sect) 
    End Sub Sub OutText2()  '和过程一类似 
    Dim i As Long 
    Dim dc As Long 
    Dim s As String 
        dc = GetDC(formhandle) 
       For i = 1 To 100000 
            s = CStr(i) 
            Call SetBkColor(dc, &HF0F0F0) 
            Call TextOut(dc, 10, 80, s, Len(s))  '文本位置改变了 
            Call Sleep(20) '延时改变了 
      Next 
        Call ReleaseDC(formhandle, dc) 
       ' Call EnterCriticalSection(sect) 
      '  Call LeaveCriticalSection(sect) 
    End Sub 
    '关于为何使用gdi 函数输出文本,这是一个很重要的内容; 
    '程序在记数时用了难用的TextOut 函数,而没有使用标签控件,这是因为 
    'vb的组件不都是线程安全的,当多线程访问不是线程安全的组件,那么会 
    '产生严重错误。 'mailto:[email protected] 
    '作者:萧寒(410000)
      

  3.   

    MSDN:BOOL TerminateThread(
      HANDLE hThread,    // handle to thread
      DWORD dwExitCode   // exit code
    );Return Values
    If the function succeeds, the return value is nonzero.If the function fails, the return value is zero. To get extended error information, call GetLastError. 你没有校验该函数的返回值, 应该是失败返回.
    你在TerminateThread()调用后追加如下代码, 查看执行结果.
    再做处理.---------------------------------------
    LPVOID lpMsgBuf;
    FormatMessage( 
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM | 
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        GetLastError(),
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
        (LPTSTR) &lpMsgBuf,
        0,
        NULL 
    );
    // Process any inserts in lpMsgBuf.
    // ...
    // Display the string.
    MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
    // Free the buffer.
    LocalFree( lpMsgBuf );
    ------------------------------
      

  4.   

    当你结束程序时用End
    不要用什么Unload