0

我隐约记得 WinAPI 提供了一个叫做 APC 的东西,它允许你指示一个线程代表你执行一个函数,它会在它找到时间执行它时执行它。线程不需要等待信号,但内核为其维护 APC 队列并指示线程执行队列中的项目。

我做了一些研究如何在 .NET 中做到这一点,但到目前为止我还没有找到一种方法来做到这一点。我知道 BeginInvoke 但这仅适用于 UI 控件的上下文,我相信?

我将如何在 .NET 环境中执行此操作?

谢谢!

4

2 回答 2

3

这在 .NET 中有所暴露,在 APC 用于 I/O 完成回调的非常特殊的情况下。这是 APC 非常常见的用途。它是相当低级的,就像 APC 一样,核心方法是 ThreadPool.BindHandle(),它设置管道以允许回调在线程池线程上执行托管代码。然而,启动重叠 I/O 的调用并非如此,这取决于您的 pinvoke。否则,这已经被执行 I/O 的各种类及其 BeginXxxx() 方法(如 FileStream、PipeStream、Socket 等)巧妙地包装了。

您自己的 APC 需要做的下一件事是将线程置于警报等待状态,这等效于 WaitForSingleObjectEx(),bAlertable 参数的值为 TRUE。这被 CLR 严密包裹,它在等待的警报状态中具有很大的利害关系,因为托管线程是否可以安全中止非常重要。Afaik,您在托管代码中调用的所有等待都是可警报的,包括 Thread.Join() 和 Thread.Sleep() 等方法。忽略 WaitHandle.WaitXxx 重载中名为“exitContext”的布尔参数,这意味着别的东西。

于 2012-08-11T15:24:17.237 回答
1

一个线程只有在阻塞一组 API 时才能执行 APC。当设置了“Alertable”标志时,该集合包括 GetMessage() 和“BlahEx”调用(例如 SleepEx)。线程确实必须等待一个信号——一个线程不能被“转移”来运行 APC 或其他任何东西,除非它涉及到线程间通信。

不确定 .NET 是否有托管的 SleepEx() 或类似的,但我相信托管线程可以以一种或另一种方式执行 APC(帮助我,.NETters!),而无需求助于非托管代码。

于 2012-08-11T10:28:44.260 回答