I have an external service that is very fast (responses faster than 50ms in SoapUI tests).
But when I use this service inside my .NET Core application, it takes > 500ms on my development machine. (And over 1 second in the production server)
I noticed that Visual Studio only generates "Async" methods for the methods of the external service. So I have a doSomething()
method on the service, and .NET maps it to doSomethingAsync()
.
To call this method, I just add a ".Result" in the end, as I need the response and I don't need it running asynchronously.
var result = client.doSomethingAsync().Result;
I have here a profiler (DynaTrace) looking at the server and it is showing a call to SendAsync()
method to call the external service URL. I don't use any SendAsync()
on my application. I don't even have any HttpClient
class instance on my code!
I guess .NET is somehow encapsulating my synchronous call inside an asynchronous call, and then just waiting for the response to resume code execution... And I guess it's creating a lot of overhead processing for something that should be simple and fast.
So the question is: How can I make the external service method calls faster in .NET Core?
Bellow is the relevant part of the code:
EndpointAddress address = new EndpointAddress(baseExternalAccess.UrlService);
BasicHttpBinding binding = new BasicHttpBinding();
binding.MaxReceivedMessageSize = 2147483647;
binding.OpenTimeout = new TimeSpan(1, 0, 0);
binding.SendTimeout = new TimeSpan(1, 0, 0);
binding.Security.Mode = BasicHttpSecurityMode.Transport;
Stopwatch stopwatch = new Stopwatch();
using (MyServiceSoapClient cliente = new MyServiceSoapClient(binding,address))
{
stopwatch.Reset();
stopwatch.Start();
var result = cliente.doSomethingAsync().Result;
stopwatch.Stop();
logger.Information("Time: " + stopwatch.ElapsedMilliseconds.ToString() + "ms");
}
Edit: To clarify the problem, I create two new projects from scratch. One using .NET Core and another one using .NET Framework.
.NET Core
- Right Click on the Project
- Add -> Connected Service
- Choose "Microsoft WCF Web Service Reference Provider"
- Inform the service wsdl URI, click GO
- Inform a Namespace, click Next
- Change nothing, click Finish
- Wait for Visual Studio to discover the service and create it's stuff.
.NET Framework
- Right Click on the "References" -> Add Service Reference...
- On the Address box, inform the service wsdl url, click GO.
- Inform a Namespace, click "Advanced"
- Uncheck "Allow generation of asynchronous operations", click OK.
- Click Ok and wait for VS to create it's stuff.
Then, on both projects, I made a simple call to the same method using same parameters. In fact, the code is almost the same, the only difference is that on the .NET Core version, the method name is "doSomethingAsync()" and I have to use ".Result" after the method name, while in the .NET Framework version, the method name is "doSomething()" and I can call it directly.
Edit 2: Every time I run this test I get similar results... The first call to the service method always is ~700ms faster on the .NET Framework version. The next 9 calls has similar timings (but the .NET Framework is always slightly faster).
On my program, I just need to call the service once, so only the time of the first call is important to me.
Edit 3: Ok, looks like .NET Core has some overhead delay to access web services.
I made four versions of a C# Console Application that only makes 10 requests to this external service and measure the time using a Stopwatch:
- .NET Framework 2.0 (Using Web Reference)
- .NET Framework 4.6.1 (Using WCF Service Reference)
- .NET Core 2.1 (Using WCF Web Service Reference)
- .NET Core 2.2 (Using WCF Web Service Reference)
Here are the results:
Test .NET Framework 2.0 Web Reference
Time: 1502ms
Time: 762ms
Time: 693ms
Time: 728ms
Time: 763ms
Time: 644ms
Time: 845ms
Time: 688ms
Time: 667ms
Time: 676ms
Total time: 7993ms
Test .NET Framework 4.6.1 WCF Reference
Time: 1770ms
Time: 675ms
Time: 619ms
Time: 644ms
Time: 895ms
Time: 671ms
Time: 611ms
Time: 702ms
Time: 655ms
Time: 741ms
Total time: 8251ms
Test .NET Core 2.1 WCF Reference
Time: 2984ms
Time: 759ms
Time: 899ms
Time: 874ms
Time: 756ms
Time: 792ms
Time: 922ms
Time: 1001ms
Time: 767ms
Time: 679ms
Total time: 10810ms
Test .NET Core 2.2 WCF Reference
Time: 3167ms
Time: 796ms
Time: 707ms
Time: 732ms
Time: 929ms
Time: 828ms
Time: 775ms
Time: 847ms
Time: 957ms
Time: 884ms
Total time: 10877ms
As the results shows, the biggest issue is with the first request. It takes longer than the other 9 request and the final 9 requests have similar timings on all te tests (But .NET Core ones are still slightly slower).
My application makes only one request to the Web service, so only the first call time is important to me.
So my conclusions is that .NET Core is just slow with WCF Web Services.