我有一个非托管DLL,如果输入参数值很大,该函数可以运行很长时间,有时这是可取的但不总是。
我怎样才能在c#中调用此函数,以便在需要时可以中止它?
到目前为止,我已经尝试将调用放在一个单独的线程中,但是中断和中止似乎都不会停止进程,该进程在100%CPU运行直到dll完成。
是否可以终止正在运行的dll代码?
答案 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以允许优雅的中止。