与命名管道和 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 服务的进程间通信:线程问题的主要内容,如果未能解决你的问题,请参考以下文章