Reputation: 8033
I have seen several similar questions, but I couldn't solve this problem based on their answers.
I have the following WCF service for communicating between to apps running on the same server, note that ConcurrencyMode
is set to Multiple
:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, UseSynchronizationContext = false, ConcurrencyMode = ConcurrencyMode.Multiple)]
internal class MyService : ServiceBase, IMyService
{
...
}
We have a WPF app in which we create the service instance the following way:
var serv = new MyService();
var servHost = new ServiceHost(serv, new Uri("..."));
servHost.AddServiceEndpoint(typeof(IMyService), ServiceBase.DefaultInterProcessBinding, string.Empty);
servHost.Open();
Where ServiceBase.DefaultInterProcessBinding is the following:
public static readonly Binding DefaultInterProcessBinding = new NetNamedPipeBinding()
{
CloseTimeout = TimeSpan.FromHours(1),
OpenTimeout = TimeSpan.FromHours(1),
ReceiveTimeout = TimeSpan.MaxValue,
SendTimeout = TimeSpan.FromHours(1),
HostNameComparisonMode = HostNameComparisonMode.StrongWildcard,
MaxBufferSize = 1073741824,
MaxBufferPoolSize = 524288,
MaxReceivedMessageSize = 1073741824,
TransferMode = TransferMode.Buffered,
ReaderQuotas = new XmlDictionaryReaderQuotas()
{
MaxDepth = 32,
MaxStringContentLength = 8192,
MaxArrayLength = 16384,
MaxBytesPerRead = 4096,
MaxNameTableCharCount = 16384
}
};
When we send multiple requests in parallel to this service, for some reason it only processes one single request at a time. (It is easy to test deterministically, because we have rather long running requests, so it can be seen very clearly that we call 3 requests in parallel at the client side, and on the server side they are getting processed sequentially one at a time.)
What can be the reason for this? What other config parameters should I check?
(UPDATE: the code I am calling the service from the client is similar to this:
Task.Factory.StartNew(() =>
{
serviceClient.Foo();
});
Task.Factory.StartNew(() =>
{
serviceClient.Bar();
});
Task.Factory.StartNew(() =>
{
serviceClient.Baz();
});
By debugging I can see, that all three requests are called immediately, but they are processed one at a time on the server.)
UPDATE 2: The problem is probably not on the server, but on the client. If I create a new client object for the calls, then they get processed in parallel properly. I create the client the following way:
var factory = new ChannelFactory<IMyService>(ServiceBase.DefaultInterProcessBinding, new EndpointAddress("..."));
serviceClient = factory.CreateChannel();
Should I configure something else on the factory or the channel?
Upvotes: 4
Views: 1530
Reputation: 8033
I figured out the problem wasn't on the server, but rather on the client side.
It seems that if you create a channel with a ChannelFactory
, you have to explicitly call Open()
on it. Otherwise the framework is going to call EnsureOpened()
every time you call a request, and EnsureOpened()
will block until the previous request is completed, so effectively only one request will be sent at a time.
(Details here: http://blogs.msdn.com/b/wenlong/archive/2007/10/26/best-practice-always-open-wcf-client-proxy-explicitly-when-it-is-shared.aspx)
So changing this code
var factory = new ChannelFactory<IMyService>(ServiceBase.DefaultInterProcessBinding, new EndpointAddress("..."));
serviceClient = factory.CreateChannel();
to this:
var factory = new ChannelFactory<IMyService>(ServiceBase.DefaultInterProcessBinding, new EndpointAddress("..."));
serviceClient = factory.CreateChannel();
((IClientChannel)serviceClient).Open();
solved the problem, now the requests are sent properly in parallel.
(By the way I needed quite a lot of googling to find this solution, it's strange to me why this issue isn't advertised more strongly on MSDN.)
Upvotes: 6