0

How can I make the WCF server instance (the instance of the class in the .svc.cs / .svc.vb file) stay alive between requests?

It's a stateless, read-only type of service: I'm fine with different clients reusing the same instance. However, it's not thread-safe: I don't want two threads to execute a method on this instance concurrently.

Ideally, what I'm looking for is that WCF manages a "worker pool" of these instances. Say, 10. New request comes in: fetch an instance, handle the request. Request over, go back to the pool. Already 10 concurrent requests running? Pause the 11th until a new worker is free.

What I /don't/ want is per-client sessions. Startup for these instances is expensive, I don't want to do that every time a new client connects.

Another thing I don't want: dealing with this client-side. This is not the responsibility of the client, which should know nothing about the implementation of the server. And I can't always control that.

I'm getting a bit lost in unfamiliar terminology from the MSDN docs. I have a lot working, but this pool system I just can't seem to get right.

Do I have to create a static pool and manage it myself?

Thanks

PS: A source of confusion for me is that almost anything in this regard points toward the configuration of the bindings. Like basicHttp or wsHttp. But that doesn't sound right: this should be on a higher level, unrelated to the binding: this is about the worker managers. Or not?

Seymour
  • 7,043
  • 12
  • 44
  • 51
hraban
  • 1,819
  • 1
  • 17
  • 27
  • 2
    what makes you think "Startup for these instances is expensive" – ChrisBint Mar 06 '15 at 15:02
  • @chrisbint profiling. There is a lot going on, including communication with other internal services. we're talking >1sec. – hraban Mar 06 '15 at 15:03
  • 1
    **Either** you have to make it a singleton - then it'll stay around, but in that case, it **must be** thread-safe - or then you leave it as is, and **do not** reuse it between requests, but each request gets its own, fresh copy of the service class (the *per-call* activation model - recommend best practice) – marc_s Mar 06 '15 at 15:28
  • seriously? Ok, that's annoying, but it confirms my suspicions. I'll have to roll my own worker pool. If you post it as an answer I can accept it. – hraban Mar 06 '15 at 15:32

1 Answers1

0

In the event that you have a WCF service that centralizes business logic, provides/controls access to another “single” backend resource (e.g. data file, network socket) or otherwise contains some type of shared resource, then you most likely need to implement a singleton.

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

In general, use a singleton object if it maps well to a natural singleton in the application domain. A singleton implies the singleton has some valuable state that you want to share across multiple clients. The problem is that when multiple clients connect to the singleton, they may all do so concurrently on multiple worker threads. The singleton must synchronize access to its state to avoid state corruption. This in turn means that only one client at a time can access the singleton. This may degrade responsiveness and availability to the point that the singleton is unusable as the system grows.

The singleton service is the ultimate shareable service, which has both pros(as indicated above) and cons (as implied in your question, you have to manage thread safety). When a service is configured as a singleton, all clients get connected to the same single well-known instance independently of each other, regardless of which endpoint of the service they connect to. The singleton service lives forever, and is only disposed of once the host shuts down. The singleton is created exactly once when the host is created.

https://msdn.microsoft.com/en-us/magazine/cc163590.aspx

Seymour
  • 7,043
  • 12
  • 44
  • 51
  • Hi seymour, just wanted to say thanks for your reply. I'm not going to accept it because this solution requires me to manage the worker pool and synchronization, which is not what I want. But thanks for taking the time, sorry for not replying earlier. – hraban Jul 26 '15 at 14:36