We have a web service that sends requests to a windows service which hosts a WCF service for processing.
The interface is simple:
namespace MyApp
{
[ServiceContract]
public interface IMyApp
{
[OperationContract]
string DoSomething(string xml);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
class MyAppWcf : IMyApp
{
public string DoSomething(string xml)
{
Customer customer = GlobalObject.GetCustomer(xml); //millisecs
return customer.DoSomething(xml); //Takes 5-10 seconds
}
}
}
GlobalObject is instantiated on the WindowsService.OnStart() and contains all the static data the customer objects need.
The interface DoSomething() will be called up to ca. 30 different clients.
Questions:
1. What is the default threading behaviour now? Will each call have to wait until the last one is finished?
2. What effect will changing InstanceContextMode?
REAL question:
There are up to 1000 customer objects, 2 different customer objects can be called in parallel, but the same one cannot. e.g.
DoSomething(“Customer 1”); => Goes ahead. Answer in 10 seconds
DoSomething(“Customer 2”); => Goes ahead in parallel with the above call.
DoSomething(“Customer 2”); => Will wait for last call of DoSomething(“Customer 2”) to finish
What should my service behavior settings be and do I have to implement a lock mechanism to prevent the same object being processed more than once in parallel?
Thanks.
Edit 2: GlobalObject.GetCustomer() just retrieves the customer mentioned in the XML from a dictionary.
OK. I’m not sure I knew that
ConcurrencyModeis ignored when usingPerCallinstancing, but looking at my own project, I usePerCallinstancing and don’t specify any value forConcurrencyMode. So apparently, I did know this at one point and just failed to document it in my code. That is now corrected.My project works a lot like you’ve described yours, and I use
InstanceContextMode.PerCallas I’ve already mentioned. Here’s what this means.MyAppWcfInst.DoSomething( "<customer id=A/>" );MyAppWcfInst.DoSomething( "<customer id=B/>" );MyAppWcfInst.DoSomething( "<customer id=B/>" );All three clients will interact with your WCF service simultaneously, but each of them will have its own instance and operate within a separate thread. So while each call by each client is single-threaded, they can be active at the same time. This means that the list of Customer objects can be accessed by multiple clients at the same time.
Client1 and Client2 can be operating in parallel since they deal with different Customer objects, but Client3 needs to wait until Client2 is finished before it can “do something” with CustomerB. All this means is that you need to synchronize access within each Customer object. In other words, the logic inside the
Customer.DoSomething()method needs to have a synchronization lock to prevent multiple clients from operating on the Customer at the same time.This is the way my WCF service works. Hope this helps.