5

我想 WaitForMultipleObjects 两种不同的类型:

  • 一个“事件等待句柄”
  • 一个'Process.Handle' ==> intptr

我不知道如何(以适当的方式)将“process.Handle”转换为 WaitHandle 以使以下代码正常工作:

   var waitHandles = new WaitHandle[2];
   waitHandles[0] = waitHandleExit;
   // Next line is the offending one:
   waitHandles[1] = new SafeWaitHandle(process.Handle, false);
   int waitResult = WaitHandle.WaitAny(waitHandles, timeOut);

我收到错误:

Error   1   Cannot implicitly convert type 'Microsoft.Win32.SafeHandles.SafeWaitHandle' to 'System.Threading.WaitHandle' ...

有人知道等待进程和 EventWaitHandle 的正确方法吗?

更新...我选择答案的原因。

首先感谢所有人:Jaroen、Slugart 和 Sriram。所有的答案都非常好。

  • Jaroen 解决方案由于我忽略的原因在我的机器上不起作用。我的“退出”事件从未发生(也许仅在 Disposed 上?)。
  • Slugart 解决方案效果很好,我在红色答案之前尝试了它。
  • Sriram 解决方案效果很好,我选择了它,因为我没有创建错误的 EventWaitHandle,并且根据我的愿景似乎更干净。

十分感谢!!!

4

3 回答 3

8

您可以将代表的 WaitHandle 子类化Process.Handle并使用它的实例WaitHandle来等待。

public class ProcessWaitHandle : WaitHandle
{
    private readonly Process process;
    public ProcessWaitHandle(Process process)
    {
        this.process = process;
        this.SafeWaitHandle = new SafeWaitHandle(process.Handle, false);
    }
}

var waitHandles = new WaitHandle[2]
{
    waitHandleExit,
    new ProcessWaitHandle(process)
};
int waitResult = WaitHandle.WaitAny(waitHandles, timeOut);
于 2014-11-10T20:38:01.887 回答
2

进程句柄不是自然可等待的,也不与 WaitHandle 位于同一继承树中。您需要将它包装在一个事件中(它确实扩展了 WaitHandle),例如:

 ManualResetEvent resetEvent = new ManualResetEvent(true);
 resetEvent.SafeWaitHandle = new SafeWaitHandle(new IntPtr(process.Handle.ToPointer()), false);
 waitHandles[1] = = resetEvent;

所有 WaitHandle 实现都将使用 SafeWaitHandle:“SafeWaitHandle 类由 System.Threading.WaitHandle 类使用。它是 Win32 互斥锁以及自动和手动重置事件的包装器。”

于 2014-11-10T20:42:23.687 回答
2

您可以创建自己的 EventWaitHandle 并将其设置在Process.Exited事件中:

var waitHandle = new ManualResetEvent(false);
process.Exited += (sender, e) => waitHandle.Set()
waitHandles[1] = waitHandle;
于 2014-11-10T20:34:21.843 回答