我已经基于 ServiceBase 类创建了一个 Windows 服务。在此服务中,我创建了 NamedPipeClientStream (m_Stream) 的一个实例。连接此流后,我使用 BeginRead() 方法开始异步读取:
m_Stream.BeginRead( m_ReadBuffer, 0, 2, ReadAsyncCallback, m_ReadInfo );
在确实被调用的回调例程 ReadAsyncCallback 中,我为流调用了 EndRead()(它给出了读取的字节数,在本例中为 2)。接下来,我想向原始线程发出读取已完成的信号。为此,我使用 Dispatcher.Invoke 方法:
m_Dispatcher.Invoke( new ReadDelegate( this.OnRead ), bytesRead);
(m_Dispatcher 是在原始线程中使用 System.Windows.Threading.Dispatcher.CurrentDispatcher 创建的。)
此时我希望在原始线程中调用 OnRead 方法,但事实并非如此。 Invoke() 方法没有返回,它似乎“挂起”了。
我希望有人能帮我解决这个问题。如果您需要更多信息,请告诉我,我会尽快提供给您。
您好, 理查德
最佳答案
System.Windows.Threading.Dispatcher
需要正确配置的 SynchronizationContext
才能正常工作。在 WPF 应用程序的上下文中,会自动为您创建同步上下文,但在您的 Windows 服务中不会发生这种情况,这就是您看到挂起的原因。
此外,除了同步上下文,因为我相信 Dispatcher
的工作方式类似于 Windows 中的 Control.Invoke
或 BackgroundWorker
窗体,您的 Windows 服务主线程必须泵送消息循环,以便您能够将调用注入(inject)其中。
我写了一篇博客,介绍 BackgroundWorker
类如何根据其运行的上下文(Windows 窗体、控制台或 Windows 服务)做出不同的 react ,您可能会发现这是一篇有趣的文章,因为该类使用的机制类似于 WPF Dispatcher
。
最后,要更深入地了解同步上下文的工作原理,您应该阅读:
关于c# - Windows 服务中异步读取期间的 Dispatcher.Invoke 'hangs',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7432867/