中止对非托管DLL的调用

hul*_*ist 13 c# dll multithreading unmanaged abort

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

我如何在c#中调用此函数以便在需要时可以中止它?

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

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

Han*_*ant 27

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

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

  • 不,应用程序域对非托管代码毫无意义。 (2认同)

Fra*_*ack 5

来自MSDN

如果在托管线程执行非托管代码时在托管线程上调用 Abort,则在线程返回托管代码之前不会抛出 ThreadAbortException。

所以看起来,中止托管线程是不可能的。
作为替代,你可以试着以Win32 API的非托管线程CreateThread()WaitForSingleObject()TerminateThread()。使用这里的签名。

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

一般来说,我会建议不要进行这种中断。也许您可以更改非托管 DLL 以允许正常中止。