We are creating a shared WCF channel to use with an async operation:
var channelFactory = new ChannelFactory<IWcfService>(new NetTcpBinding {TransferMode = TransferMode.Buffered}); channelFactory.Endpoint.Behaviors.Add(new DispatcherSynchronizationBehavior(true, 25)); var channel = channelFactory.CreateChannel(new EndpointAddress(new Uri("net.tcp://localhost:80/Service").AbsoluteUri + "/Test")); This calls the following service:
[ServiceContract] public interface IWcfService { [OperationContract] Task<MyClass> DoSomethingAsync(); } [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.PerCall)] public class WcfServiceImpl : IWcfService { public Task<MyClass> DoSomethingAsync() { Thread.Sleep(4000); return Task.FromResult(new MyClass()); } } [Serializable] public class MyClass { public string SomeString { get; set; } public MyClass Related { get; set; } public int[] Numbers { get; set; } } If we start 3 requests at once and simulate a long running task on the response:
using ((IDisposable)channel) { var task1 = Task.Run(async () => await DoStuffAsync(channel)); var task2 = Task.Run(async () => await DoStuffAsync(channel)); var task3 = Task.Run(async () => await DoStuffAsync(channel)); Task.WaitAll(task1, task2, task3); } } public static async Task DoStuffAsync(IWcfService channel) { await channel.DoSomethingAsync(); Console.WriteLine("Response"); // Simulate long running CPU bound operation Thread.Sleep(5000); Console.WriteLine("Wait completed"); } Then all 3 requests reach the server concurrently, it then responds to all 3 requests at the same time.
However once the response reaches the client it processes each in turn.
Response // 5 second delay Wait completed // Instant Response // 5 second delay Wait completed // Instant Response The responses resume on different threads but only runs 1 per time.
If we use streaming instead of buffered we get the expected behaviour, the client processes all 3 responses concurrently.
We have tried setting max buffer size, using DispatcherSynchronizationBehaviour, different concurrency modes, toggling sessions, ConfigureAwait false and calling channel.Open() explicitly.
There seems to be no way to get proper concurrent responses on a shared session.
Edit
I have added an image of what I believe to be happening, this only happens in Buffered mode, in streamed mode the main thread does not block.

Thread.Sleep(5000)instead of the non-blockingawait Task.Delay(5000)? Second, why are you usingTask.Runfor an async method? You should first properly apply the async/await pattern before digging deeper.Task DoStuffAsync(IWcfService channel)blocks the thread at the client, see my answer.