简体   繁体   中英

Inter-process communication with named pipe and WCF Service: threading issue

I have two processes: one GUI, the other CUI. Each of them host a simple WCF service and they communicate with each other via name pipes.

There are two buttons and a progress bar in the GUI application. 在此处输入图片说明

The "Start Running" button tells the CUI to run a task for 30 seconds. The CUI reports its progress back to the GUI, so the progress bar can be updated. The "Print" button tells the CUI to print a string.

Now if we press the "Print" button for a few times, it's fine, the CUI will print strings: 在此处输入图片说明

Then if I press the "start running" button, the CUI will print the progress to the console and report the progress back to the GUI and the progress bar gets updated: 在此处输入图片说明

Then I can press the "Print" button for a couple more times, and it works: 在此处输入图片说明

This all seems good.

But if I restart those two processes, and click the "Start Running" button first, then click the "Print" button, then both processes will be frozen: 在此处输入图片说明

It looks like a threading issue.

So it seems like if I start with clicking the print button, then everything works. But if I start with clicking the start running button, then there'll be a dead lock. Why is that?

You can download this sample from here : http://files.cnblogs.com/cuipengfei/SampleForStackOverflow.zip

The deadlock appears when you're calling worker.Print() as it doesn't create a new object for the worker, but tries to reuse the same one. If you put that call in another thread, then you see that this call is executed once worker.RunTask(30) finishes.

First I was thinking of changing the InstanceContextMode.Single to InstanceContextMode.PerCall, so it creates one object per call instead of using the same object for all calls. This didn't resolve the problem.

Re-testing your provided case study, it also works if you let finish worker.RunTask(30). So I think the problem occurs, if you have never finished a call before invoking a 2nd call. Then it tries to reuse the same server instance. Once you fully finished one call, it works as expected.

However, what solves your problem is to open multiple connections to your server:

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

Then use this for accessing the print operation:

worker2.Print();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM