My .NET Core project is generating only async methods for the WCF service. Is there any way to use synchronous methods like in regular .NET projects?
In regular .NET there was both sync and async methods like:
WcfClient.MethodName
and WcfClient.MethodNameAsync
In .NET Core there are only WcfClient.MethodNameAsync
This question helped me: How to call asynchronous method from synchronous method in C#?
But this solution causes other problems. Any ideas how to generate synchronous methods/functions?
Check this GitHub issue; they discuss some facts that you may be interested in.
You are right. Our NetCore/Netstandard support does not yet include Sync implementation of the APIs. Please note that this change is on our Roadmap as one of the parity items for the transition to .NetCore and we will update with more specific timelines as soon as it is available.
- erezvani1529 commented on Nov 29, 2016
And
Can you clarify for us what your need is for the synchronous methods? Overall, sync is much less resource efficient than async and is not something that we recommend to our customers. You can always use .GetAwaiter.GetResult() if you need to block on the async calls.
We have had some conversations with the CLR team, who provided this guidance:
If you expose an asynchronous endpoint from your library, avoid exposing a synchronous method that just wraps the asynchronous implementation. Doing so hides from the consumer the true nature of the implementation, and it should be left up to the consumer how they want to consume the implementation. If the consumer chooses to block waiting for the asynchronous implementation to complete, that’s up to the caller, and they can do so with their eyes wide open. This is even more important for the “sync over async” case than it is for the “async over sync” case, because for “sync over async,” it can lead to significant problems with the application, such as hangs.
.NET Core team has chosen to not support a true sync api for the reasons listed above (resource consumption, etc.) Even if we implement a true sync, it would end up being sync over async at some level. For this reason, we believe that adding fake sync apis would be a hindrance and not a help to our customers. Please let us know if you have any feedback regarding this. pemari-msft commented on May 11, 2017
And
Let me explain the rationale. True sync is not an option for a library if it is consuming a library that does not support true sync, as is the case for us and .NET Core. (And anyway, true sync is something of a misnomer for APIs that make network calls, but that's a different discussion.) So we have two options: create a sync-over-async wrapper, or let the caller do it. But as we have seen, the official guidance and prevailing wisdom is that exposing a wrapper should be avoided. This is with good reason, and it's similar to avoiding an async API that wraps a synchronous invocation. Avoiding such APIs not only keeps the API surface clean, it also avoids confusion. Customers will think there is true support for sync or async and expose this in their own public interface only to discover later that the underlying implementation doesn't actually support it! So we have concluded that it is best to follow the prevailing wisdom in this case.
You are correct that deadlock avoidance is essential, especially in sync-over-async scenarios, so let me say a little about how this is done. The deadlock issue arises when a thread calls an async method and then blocks waiting for the result, while the async method chain is waiting for the thread to free up so it can continue. The solution is to have the async method do its work in a different context where it won't be constrained by a limited pool of threads. This is done internally in the async method using ConfigureAwait, so deadlocks are avoided within the library itself.
If you feel that true sync is important then you can bring this up at https://github.com/dotnet/corefx to get this supported in .NET Core.
- mirobers commented on May 12, 2017
So you would either change your project to avoid Azure or fake synchronous calls.
However, in 2018, there was a change in view:
Well, after enough discussion, following the lead set by HttpWebRequest we have decided to offer sync methods as sync-over-async. This is a time buffer for our users before we deprecate the sync APIs in future versions of the library.
@copernicus365 , to keep it simpler for people, particularly those who are already using the library, our Netstandard2.0 support which includes the feature parity between desktop and Netcore, will leave the methods as-is, in the same namespace / binary of the split-per-service packages(split packages are in preview at the moment). Naturally, we’ll need to echo guidance in our docs by the .NET team about the benefits of converting to async, and try to make as clear as possible that it’s sync-over-async under the covers.
Many thanks to everyone who took the time to chime in on this thread and give us feedback!
One related note - for existing people who are already using the sync methods on .NET Desktop, these will also be moving to sync-over-async. We’re modifying the codebase to use HttpClient everywhere (both in desktop and in .NET Core), which doesn’t offer any sort of true sync. This is to get away from having separate implementations of everything (one with HttpWebRequest and one with HttpClient), which has led to many bugs and behavior differences between the different implementations.
- erezvani1529 commented on Mar 16, 2018
And the changes landed in the .NET Standard 2.0 target in May 2018.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With