13

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

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

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

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

4

2 回答 2

28

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

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

于 2010-05-06T14:35:11.990 回答
5

来自MSDN

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

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

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

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

于 2010-05-06T14:04:34.273 回答