I have this library which is purely sync. It exposes sync methods and I have clients using it.
I changed the underlying implementation to async and exposed async methods for whoever wants to use it. But now I have lots of replicated code. Async code seems to perform better. I'd like existing clients to take advantage of it and I want to eliminate code repetition.
Is there any safe way to keep a sync signature and call async implementation?
I'm specifically afraid of deadlocks when calling .Result and .Wait.
Asynchronous methods should not be exposed purely for the purpose of offloading: such benefits can easily be achieved by the consumer of synchronous methods using functionality specifically geared towards working with synchronous methods asynchronously, e.g. Task.
As a result, by applying parallel computing and asynchronous programming when dealing with independent tasks, you're able to perform these tasks way faster than with synchronous execution because they're executed at the same time.
Synchronous JavaScript: As the name suggests synchronous means to be in a sequence, i.e. every statement of the code gets executed one by one. So, basically a statement has to wait for the earlier statement to get executed. Let us understand this with the help of an example.
Or we can say await is only used with an async function. The await keyword is used in an async function to ensure that all promises returned in the async function are synchronized, ie. they wait for each other. Await eliminates the use of callbacks in .
I strongly encourge you not to do this
First, read Should I expose synchronous wrappers for asynchronous methods? and Should I expose asynchronous wrappers for synchronous methods? by Stephan Toub.
The main reasons I wouldn't do this:
Sync over Async - As you said, deadlocks. Higher or lower down the call chain, using Result
or Wait
on async maybe risky business. It really depends on which platform you run (ASP.NET, UI, Console) as each one behaves a bit differently (Even when using ConfigureAwait(false)
)
Async over Sync - Scalability. Once I see an async endpoint, I assume it is pure async, which for me, as the consumer of the API means there isn't any Thread spinning "behind my back". If your users assume the same, finding out that for every call to an async method a Thread Pool thread is used can drastically hurt performance when trying to scale out. If the users want to wrap a sync method with a Task.Run
, leave it up to them to make that call and make their on judgement on how this will affect their application
Try to start from the bottom up, or you run into deadlocks (
Console apps behave differently from web and UI apps as far as how they handle deadlocks if they're NOT properly handled. If you're using MVC, use an async task ActionResult and wrap specific synchronous calls on Task.Run(() => SYNCCODE) using async and await. Similar process with UI code, using async/await upon event methods (such as Click event handlers).
I typically wrap my sync calls with async versions and handle them as tasks. If those sync methods can utilize Async versions of .NET methods, I try to go "deeper in" where possible.
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