Cui Pengfei 崔鹏飞
Cui Pengfei 崔鹏飞

Reputation: 8305

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. enter image description here

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: enter image description here

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: enter image description here

Then I can press the "Print" button for a couple more times, and it works: enter image description here

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: enter image description here

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

Upvotes: 1

Views: 983

Answers (1)

thoean
thoean

Reputation: 1116

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();

Upvotes: 1

Related Questions