【问题标题】:Abort call to unmanaged DLL中止对非托管 DLL 的调用
【发布时间】:2011-02-16 09:52:56
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: c# dll multithreading unmanaged abort


    【解决方案1】:

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

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

    【讨论】:

    • 另一种选择是在单独的应用程序域中执行相同的操作。
    【解决方案2】:

    来自MSDN

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-02
      • 1970-01-01
      • 1970-01-01
      • 2011-09-24
      • 2011-03-04
      • 1970-01-01
      • 2014-08-18
      相关资源
      最近更新 更多