views:

152

answers:

3

Hi everyone.

I'm trying to configure some WCF stuff. Currently, I have a server which allows remote users to download files, and client. In the server, I use a ServiceHost class. I assume it should be running on a separate thread, however, the server UI (WinForms) becomes locked when someone downloads a file. Is there a way to manage the WCF threading model?

Thank you!

A: 

You shouldn't host a WCF Service inside a UI program. WCF has a very specific threading model, that will prevent your UI from running nicely.

Basically, the WCF threading scheme changes depending on the instance management behavior selected, and also when there are no requests reaching the service during a time period WCF might suspend the running thread. All of this will cause trouble with the UI.

What I do in this situations, is to create a Windows Service hosting WCF, and create a ServiceContract to expose the needed data to the monitoring UI. This UI will run independtly in it's own exe, being another client of the service, fetching the data from the service as needed.

I hope makes sense for you.

iCe
+1  A: 

"From the same Windows Form application if you were to construct the ServiceHost instance before starting the UI thread, it will run on its own thread. That means worker threads allocated from the thread pool process messages instead of the message loop. Thus, services can truly process multiple concurrent requests. "

Sphynx
This will result in functionality equivalent to the answer I gave below. Since you are creating the ServiceHost before the SycnhronizationContext.Current property gets set to an instance of WindowsFormsSynchronizationContext (e.g. before any controls have been created), your ServiceHost will not attempt to process service requests on the UI thread. The advantage of my solution is that it makes this behavior a matter of policy, so that it doesn't matter at what point you decide to create your ServiceHost.
luksan
+1  A: 

You should add a ServiceBehaviorAtttribute to the class implementing your service and set its UseSynchronizationContext property to false. This will cause calls to your service to be processed on their own thread.

Example:

[ServiceBehavior(UseSynchronizationContext=false)]
class YourService : IYourService
{
  // Service Methods
}

Just remember that if you are going to update any Controls from within your service methods, you must bear in mind the cross-thread programming model of Windows Forms.

luksan
wOW + 1 didn't know that feature!
iCe