DWORD WINAPI CalcProc(LPVOID l)
{
    ((MyDlg*)l)->Calc();
    return 0;
}
void MyDlg::Calc()
{
//此处调用动态连接库(.dll),主要是进行计算,时间有点长要30秒--5分钟
}
void MyDlg::OnBtnClick()//CDialog上单击按纽
{
    CreateThread(0,0,CalcProc,this,0,0);
}
问题是:
如果我要是在Calc()函数没有运行完,即动态连接库还没有执行完就退出CDialog就会出现非法操作的提示.否则就正常.
首先我改变不了动态库的原代码(没有).就是说要怎么强制结束dll的计算运行.
请问;我要怎么解决这个问题啊?
谢谢各位了,马上解决,立刻给分.......................

解决方案 »

  1.   

    4.3.2 ExitProcess函数
    当进程中的一个线程调用E x i t P r o c e s s函数时,进程便终止运行:
    ExitProcess
    该函数用于终止进程的运行,并将进程的退出代码设置为f u E x i t C o d e。E x i t P r o c e s s函数并
    不返回任何值,因为进程已经终止运行。如果在调用E x i t P r o c e s s之后又增加了什么代码,那么
    该代码将永远不会运行。
    当主线程的进入点函数( Wi n M a i n、w Wi n M a i n、m a i n或w m a i n)返回时,它将返回给
    C / C + +运行期启动代码,它能正确地清除该进程使用的所有的C运行期资源。当C运行期资源被
    释放之后,C运行期启动代码就显式调用E x i t P r o c e s s,并将进入点函数返回的值传递给它。这
    解释了为什么只需要主线程的进入点函数返回,就能够终止整个进程的运行。请注意,进程中
    运行的任何其他线程都随着进程而一道终止运行。
    Windows Platform SDK文档声明,进程要等到所有线程终止运行之后才终止运行。就操作
    系统而言,这种说法是对的。但是, C / C + +运行期对应用程序采用了不同的规则,通过调用
    E x i t P r o c e s s,使得C / C + +运行期启动代码能够确保主线程从它的进入点函数返回时,进程便终
    止运行,而不管进程中是否还有其他线程在运行。不过,如果在进入点函数中调用E x i t T h r e a d,
    而不是调用E x t i P r o c e s s或者仅仅是返回,那么应用程序的主线程将停止运行,但是,如果进程
    中至少有一个线程还在运行,该进程将不会终止运行。
    注意,调用E x i t P r o c e s s或E x i t T h r e a d可使进程或线程在函数中就终止运行。就操作系统而
    言,这很好,进程或线程的所有操作系统资源都将被全部清除。但是, C / C + +应用程序应该避
    免调用这些函数,因为C / C + +运行期也许无法正确地清除
      

  2.   

    windows核心编程里写的很详细4.3.3 Te r m i n a t e P r o c e s s函数
    调用Te r m i n a t e P r o c e s s函数也能够终止进程的运行:
    该函数与E x i t P r o c e s s有一个很大的差别,那就是任何线程都可以调用Te r m i n a t e P r o c e s s来终
    止另一个进程或它自己的进程的运行。h P r o c e s s参数用于标识要终止运行的进程的句柄。当进
    程终止运行时,它的退出代码将成为你作为f u E x i t C o d e参数来传递的值。
    只有当无法用另一种方法来迫使进程退出时,才应该使用Te r m i n a t e P r o c e s s。终止运行的
    进程绝对得不到关于它将终止运行的任何通知,因为应用程序无法正确地清除,并且不能避免
    自己被撤消(除非通过正常的安全机制)。例如,进程无法将内存中它拥有的任何信息迅速送
    往磁盘。
    虽然进程确实没有机会执行自己的清除操作,但是操作系统可以在进程之后进行全面的清
    除,使得所有操作系统资源都不会保留下来。这意味着进程使用的所有内存均被释放,所有打
    开的文件全部关闭,所有内核对象的使用计数均被递减,同时所有的用户对象和G D I对象均被
    撤消。
    一旦进程终止运行(无论采用何种方法),系统将确保该进程不会将它的任何部分遗留下
    来。绝对没有办法知道该进程是否曾经运行过。进程一旦终止运行,它绝对不会留下任何蛛丝
    马迹。希望这是很清楚的。
    注意Te r m i n a t e P r o c e s s函数是个异步运行的函数,也就是说,它会告诉系统,你想要
    进程终止运行,但是当函数返回时,你无法保证该进程已经终止运行。因此,如果想
    要确切地了解进程是否已经终止运行,必须调用Wa i t F o r S i n g l e O b j e c t函数(第9章介绍)
    或者类似的函数,并传递进程的句柄。
    进程中的线程何时全部终止运行
    如果进程中的所有线程全部终止运行(因为它们调用了E x i t T h r e a d函数,或者因为它们已
    经用Te r m i n a t e P r o c e s s函数终止运行),操作系统就认为没有理由继续保留进程的地址空间。这
    很好,因为在地址空间中没有任何线程执行任何代码。当系统发现没有任何线程仍在运行时,
    它就终止进程的运行。出现这种情况时,进程的退出代码被设置为与终止运行的最后一个线程
    相同的退出代码。
      

  3.   

    4.3 终止进程的运行
    若要终止进程的运行,可以使用下面四种方法:
    • 主线程的进入点函数返回(最好使用这个方法)。
    • 进程中的一个线程调用E x i t P r o c e s s函数(应该避免使用这种方法)。
    • 另一个进程中的线程调用Te r m i n a t e P r o c e s s函数(应该避免使用这种方法)。
    • 进程中的所有线程自行终止运行(这种情况几乎从未发生)。
      

  4.   

    若要终止线程的运行,可以使用下面的方法:
    • 线程函数返回(最好使用这种方法)。
    • 通过调用E x i t T h r e a d函数,线程将自行撤消(最好不要使用这种方法)。
    • 同一个进程或另一个进程中的线程调用Te r m i n a t e T h r e a d函数,线程的外部调用BOOL TerminateThread( HANDLE hThread, DWORD dwExitCode )来强行终止一个线程的运行(应该避免使用这种方法)。
    • 包含线程的进程终止运行(应该避免使用这种方法)。
    第二种与第三种强制线程退出,很可能造成在线程中分配的内存等对象无法释放。