【问题标题】:How to wait on WaitHandle without message pumping?如何在没有消息泵送的情况下等待 WaitHandle?
【发布时间】:2010-10-28 03:06:36
【问题描述】:

我想在 .NET 中调用 WaitHandle.WaitOne(TimeSpan),但我在 STA 线程上,它在等待时会发送消息。由于超出此问题范围的原因,我需要等待抽水。如何在不发送消息的情况下等待 WaitHandle 发出信号?

在某些情况下WaitHandle.WaitOne 似乎不会发送消息。但有时它确实适用于某些消息。有关更多信息,请参阅以下链接:

  1. Managed and Unmanaged Threading in Microsoft Windows
  2. Managed blocking

【问题讨论】:

  • 我知道这个问题已经得到解答,但你能给出一个方法来证明 WaitHandle.WaitOne 泵送消息吗?我真的不明白这里发生了什么,我很好奇。
  • wcoenen:我在问题中添加了链接,表明 WaitOne 有时会发送消息。

标签: .net multithreading com


【解决方案1】:

WaitForSingleObject 或 WaitForMultipleObjects 是非泵送等待;使用 p/invoke。

[DllImport("kernel32", SetLastError=true, ExactSpelling=true)]
public static extern Int32 WaitForSingleObject(SafeWaitHandle handle, Int32 milliseconds);

-奥辛

【讨论】:

  • 谢谢。我不知道您可以将 SafeWaitHandle 直接传递给 P/Invoke 方法。这很酷。感谢您的提示。
  • 是的,.NET 编组器“知道”公开 IntPtr 的类型(在本例中为 GetDangerousHandle,iirc),因此您只需替换签名中的该参数并让奇迹发生;-)
  • 由于某种原因,WaitOne() 完成的有限抽取阻止了在 Form.OnActivated 中调用 WaitOne() 时恢复最小化的表单。我花了 2 个小时来追踪到 WaitOne() 调用的错误,但感谢您在这里的回答,我可以快速修复它:) 谢谢!
【解决方案2】:

显然这是change introduced in Microsoft VistaCoWaitForMultipleHandles 现在发送WM_PAINT 消息。

Vista bug report.

一种解决方法是使用 Microsoft 的应用程序兼容性工具包为您的应用程序设置 DisableNewWMPAINTDispatchInOLE 标志。

【讨论】:

    【解决方案3】:

    如果您在一个 WPF 应用程序中,其中 Dispatcher 在托管等待期间运行消息泵,那么在等待期间禁用消息泵的最简单方法是通过Dispatcher.DisableProcessing

    // The Dispose() method is called at the end of the using statement. 
    // Calling Dispose on the DispatcherProcessingDisabled structure,  
    // which is returned from the call to DisableProcessing, will 
    // re-enable Dispatcher processing. 
    using (Dispatcher.CurrentDispatcher.DisableProcessing())
    {
        // Do work while the dispatcher processing is disabled.
        Thread.Sleep(2000);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-17
      • 2012-05-25
      • 2016-06-24
      • 2016-03-29
      • 1970-01-01
      相关资源
      最近更新 更多