中止对非托管DLL的调用

时间:2010-05-06 13:29:58

标签: c# dll multithreading unmanaged abort

我有一个非托管DLL,如果输入参数值很大,该函数可以运行很长时间,有时这是可取的但不总是。

我怎样才能在c#中调用此函数,以便在需要时可以中止它?

到目前为止,我已经尝试将调用放在一个单独的线程中,但是中断和中止似乎都不会停止进程,该进程在100%CPU运行直到dll完成。

是否可以终止正在运行的dll代码?

2 个答案:

答案 0 :(得分:27)

如果非托管代码是“可警告的等待状态”,则该代码仅可中止。它不会燃烧100%的cpu周期。 P / Invoking TerminateThread可以工作,假设您可以获得线程句柄,.NET非常困难。无论如何它都无济于事,你会泄漏线程堆栈。在1兆字节时,您将很快耗尽虚拟内存。即使这只是偶尔的需要,你仍然有可能遇到重大问题,因为线程已经改变了全局程序状态而你不知道如何恢复它。

中止非托管代码的唯一好方法是在一个单独的进程中运行它并使用Process.Kill()将其射入脑中。操作系统将清理弹片。您需要为DLL编写一个小的托管程序,并使用其中一个进程互操作工具与之通信。套接字,命名管道,.NET远程处理,WCF,你可以选择。

答案 1 :(得分:4)

来自MSDN

  

如果在托管线程上调用Abort   在执行非托管代码时   不抛出ThreadAbortException   直到线程返回托管   代码。

所以看来,中止托管线程是不可能的 作为替代方案,您可以尝试使用Win32 API CreateThread()WaitForSingleObject()TerminateThread()启动非托管线程。使用here中的签名。

我自己没有尝试过,但肯定会引入一些风险,因为你无法确定你在哪个执行点杀死了线程。它也可能导致资源泄漏。 MSDN列出了TerminateThread()引用的一些副作用。

总的来说,我会建议不要这种中断。也许你有可能改变非托管DLL以允许优雅的中止。