与命名管道和 WCF 服务的进程间通信:线程问题

Posted

技术标签:

【中文标题】与命名管道和 WCF 服务的进程间通信:线程问题【英文标题】:Inter-process communication with named pipe and WCF Service: threading issue 【发布时间】:2012-02-17 21:55:14 【问题描述】:

我有两个进程:一个是 GUI,另一个是 CUI。 它们每个都托管一个简单的 WCF 服务,并通过名称管道相互通信。

GUI 应用程序中有两个按钮和一个进度条。

“开始运行”按钮告诉 CUI 运行任务 30 秒。 CUI 将其进度报告回 GUI,因此可以更新进度条。 “打印”按钮告诉 CUI 打印一个字符串。

现在如果我们按下“打印”按钮几次,没关系,CUI 将打印字符串:

然后,如果我按下“开始运行”按钮,CUI 会将进度打印到控制台并将进度报告回 GUI,并且进度条会更新:

然后我可以再按几次“打印”按钮,它就可以了:

这一切看起来都很好。

但是如果我重新启动这两个进程,然后先单击“开始运行”按钮,然后单击“打印”按钮,那么两个进程都会被冻结:

看起来像是线程问题。

所以看起来如果我从单击打印按钮开始,那么一切正常。 但是如果我从点击开始运行按钮开始,那么就会出现死锁。 这是为什么呢?

您可以从这里下载此示例:http://files.cnblogs.com/cuipengfei/SampleFor***.zip

【问题讨论】:

【参考方案1】:

当您调用 worker.Print() 时会出现死锁,因为它不会为 worker 创建新对象,而是尝试重用同一个对象。如果您将该调用放在另一个线程中,那么您会看到该调用在 worker.RunTask(30) 完成后执行。

首先,我考虑将 InstanceContextMode.Single 更改为 InstanceContextMode.PerCall,因此它每次调用都会创建一个对象,而不是为所有调用使用同一个对象。这并没有解决问题。

重新测试您提供的案例研究,如果您让完成 worker.RunTask(30),它也可以工作。所以我认为问题出现了,如果你在调用第二个电话之前从未完成过一个电话。然后它尝试重用相同的服务器实例。一旦你完全打完一个电话,它就会按预期工作。

但是,解决您的问题的方法是打开到您的服务器的多个连接:

NetNamedPipeBinding binding2 = new NetNamedPipeBinding();
worker2 = ChannelFactory<IWorker>.CreateChannel(binding2, endpointAddress);

然后使用它来访问打印操作:

worker2.Print();

【讨论】:

顺便说一句,我们也可以通过在另一个线程中运行任务来解决这个问题。

以上是关于与命名管道和 WCF 服务的进程间通信:线程问题的主要内容,如果未能解决你的问题,请参考以下文章

为啥线程在进程间通信期间会破坏命名管道?

Windows进程间通信—命名管道

Linux-进程间通信

Linux-进程间通信

Linux-进程间通信

Linux - 进程间通信与线程通信方式