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

时间:2012-02-17 21:55:15

标签: .net multithreading wcf ipc named-pipes

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

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

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

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

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

然后我可以多次按下“打印”按钮,它可以工作: enter image description here

这一切似乎都很好。

但是,如果我重新启动这两个进程,然后先单击“开始运行”按钮,然后单击“打印”按钮,则两个进程都将被冻结: enter image description here

这看起来像是一个线程问题。

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

您可以从此处下载此示例:http://files.cnblogs.com/cuipengfei/SampleForStackOverflow.zip

1 个答案:

答案 0 :(得分:1)

当您调用worker.Print()时会出现死锁,因为它不会为worker创建新对象,但会尝试重用相同的对象。如果你把那个调用放在另一个线程中,那么你会看到一旦worker.RunTask(30)完成就会执行这个调用。

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

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

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

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

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

worker2.Print();