dotnet / dotnet/wcf

Sync methods seems to hang

Open
#5,417 5 comments 0 reactions 1 assignee Claimed by @mconnew View on GitHub
triaged
Dominant language
C#
Stars
1.8k
Forks
576
Avg merge
6d 9h
Merged PRs (30d)
2

Description

**Describe the bug**
When running version 6.2 of this library using net.tcp and having a sync service interface, then calling the methods from a task based application makes the code seem to hang.

**To Reproduce**
Hi,
This seems to still be an issue.

In NET framework 4.8 if you call a sync method from a Task based method everthing just works.
If you do the same in a net6 app, the application seems to hang while the threadpool slowly ramps up its worker threads.

i.e.
```csharp
using System.Threading.Tasks;
using System;
using System.Collections.Generic;
using System.ServiceModel;

namespace Whatever
{
[ServiceContract]
public interface IWcfClient
{
[OperationContract]
string SyncMethod();
}
static class Program
{
static async Task Main(string[] args)
{
await RunTest();
return 0;
}
private static async Task RunTest()
{
List tasks = new List();
List results = new List();
IWcfClient wcfClient = default; // Create this via ChannelFactory
for (int i = 0; i < 100; i++)
{
Console.WriteLine($"Start new [{i}] {DateTime.Now}");
var iLocal = i;
var task = Task.Run(async () =>
{

string data = wcfClient.SyncMethod();
lock (results)
{
results.Add(data);
}
Console.WriteLine($"##Got result [{iLocal}] " + DateTime.Now);
});
tasks.Add(task);
}

Task.WaitAll(tasks.ToArray());
Console.WriteLine($"##Got results [{results.Count}] " + DateTime.Now);
}
}
}
```

**Expected behavior**
Code runs as in net framework 4.8, so its possible to migrate from net framework 4.8 to net 6 in a client

**Additional context**
If you run the above example code in NET Framework 4.8 it runs very quickly - if you run the same code in net6 and most likely also higher, it seems to just hang.

This behavior breaks legacy applications that tries to convert from net framework to a net6 wcf client using the same sync api.

Running in NET6 - the first results comes in quickly, and then it just hangs and after a while the remaining tasks completes when the threadpool has ramped up enough threads to continue.

We have this issue in a service that works as a "proxy" between a cloud environment using grpc and an onprem legacy application in WCF.

When the service starts it immediately receives a lot of requests - many more than it has cores (default min threads in threadpool) - this is not a problem in net framework 4.8, but in NET6 the WCF client it uses to communicate with the legacy WCF service exhibits this behavior of hanging - and because the service continues to receive requests, it snowballs into many thousands of tasks queued that will most likely never finish because threadpool is ramping too slowly up and because of this seemingly "new" change in behavior in between net framework 4.8 and net6.

You can "fix" this behavior by forcing the thread pool to start with many more worker threads, but I think that is a work around and I would prefer a better solution if any exist.

I know its a bad pattern to call a sync method from a task based code base, but you cannot magically switch entire codebases to Task based overnight - its much easier to change from target framework net48 -> net6.0.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.