Brandon
Brandon

Reputation: 3276

Why are My Async Tasks Waiting for One Another to Finish?

private async void StartTasks_Click(object sender, RoutedEventArgs e) 
{
    await Task.WhenAll(GetSomeData());
    lblResult.Text = "Got data?";
}

private async Task GetSomeData()
{
    System.Net.ServicePointManager.DefaultConnectionLimit = 16;
    ServiceClient _proxy = new ServiceClient();

    //*** the wcf proxy service methods just sleep for 5 seconds.
    var t1 = _wcfProxy.A();
    var t2 = _wcfProxy.A();
    var t3 = _wcfProxy.A();
    var t4 = _wcfProxy.A();

    await Task.WhenAll(t1,t2,t3,t4);
}

When I click my button, I'm expecting my label text to be set in 5 seconds (since my WCF method calls are just sleeping for 5 seconds). Well, It's taking 10 seconds. Now, when I only make three service calls, instead of four, the label gets set in 5 seconds.

When I watch the Calls count in the performance monitor when I make all four calls, I only see 3 come in, then the other 1 comes in after the first three finish.

Upvotes: 1

Views: 115

Answers (1)

noseratio
noseratio

Reputation: 61736

Check this MSKB article: WCF service may scale up slowly under load.

To sum up, it appears your WCF service's default IOCP thread pool is starving (it's hard to tell why; check with ThreadPool.GetMinThreads and ThreadPool.GetAvailableThreads). So most likely, when you block a WCF thread with Thread.Sleep while serving _wcfProxy.A(), there isn't another thread available to serve _wcfProxy.B(), so the B request gets queued until A has completed.

Try implementing WorkerThreadPoolSynchronizer and WorkerThreadPoolBehaviorAttribute as described in that article, apply [WorkerThreadPoolBehavior]to and A and B and see if that solves the problem.

Upvotes: 1

Related Questions