c# - Windows 服务中异步读取期间的 Dispatcher.Invoke 'hangs'

标签 c# multithreading asynchronous dispatcher

我已经基于 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.InvokeBackgroundWorker窗体,您的 Windows 服务主线程必须泵送消息循环,以便您能够将调用注入(inject)其中。

我写了一篇博客,介绍 BackgroundWorker 类如何根据其运行的上下文(Windows 窗体、控制台或 Windows 服务)做出不同的 react ,您可能会发现这是一篇有趣的文章,因为该类使用的机制类似于 WPF Dispatcher

Inside BackgroundWorker

最后,要更深入地了解同步上下文的工作原理,您应该阅读:

It's All About the SynchronizationContext

关于c# - Windows 服务中异步读取期间的 Dispatcher.Invoke 'hangs',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7432867/

相关文章:

c# - 如何在 C# 中为计时器实现任务异步?

c# - JS/C#如何知道我刚刚点击或操作的元素id或xpath?

python - 使用多线程在不同的运行中获得不同的结果

java - 启动 Thread 或进行计算的 SwingWorker 时的 Swing 伪 block

c++ - 使用use_future的Boost Asio async_send_to多播不起作用

javascript - 如何使用 Node.js 和 Express 在 JavaScript 中通过 GET 请求更改页面?

c# - Visual Studio 组件设计器可以访问和修改项目 .config 文件吗?

c# - 为什么只读成员在结构中而不是在类中

iphone - 在后台线程上绘制上下文

mysql - 如何在nodejs中进行动态的mysql查询次数?