How to mix synchronization and asynchronous code safely?

I have this library which is pure synchronization. It provides synchronization methods, and I have clients that use it.

I changed the base implementation to async and exposed the async methods for those who want to use it. But now I have a lot of replicated code. Async code seems to work better. I would like existing clients to take advantage of this, and I want to eliminate code duplication.

Is there a safe way to keep the synchronization signature and execute an asynchronous implementation?

I specifically fear deadlocks when calling .Result and .Wait.

+13
c # asynchronous deadlock async-await
Jun 18 '14 at 10:59
source share
2 answers

I strongly forbid you not to do this

Read first Should I expose synchronous wrappers for asynchronous methods? and Should I open asynchronous wrappers for synchronous methods? from Stephan Toub.

The main reasons why I will not do this:

  • Async sync - as you said, deadlocks. Up or down the call chain using Result or Wait in async is probably a risky business. It depends on what platform you are running (ASP.NET, UI, Console), since each one behaves differently (even when using ConfigureAwait(false) )

  • Async over Sync - Scalability As soon as I see the async endpoint, I assume that it is pure async, which for me, since the consumer API means that there is not a single thread rotating โ€œbehind my backโ€. If your users assume the same thing, figuring out that for each call to the asynchronization method, a thread thread is used, which can damage performance when trying to scale. If users want to wrap the synchronization method using Task.Run , leave it for them to make this call , and decide how this will affect their application.

+14
Jun 19 '14 at 3:43
source share

Try to start from the bottom up, or you will run into dead ends (

Console applications behave differently from web and user interface applications, how much they handle locks if they are NOT handled properly. If you use MVC, use the ActionResult asynchronous task and wrap the special synchronous calls in Task.Run (() => SYNCCODE) using async and expect. A similar process with UI code using async / await when using event methods (such as Click event handlers).

I usually transfer my synchronization calls to asynchronous versions and treat them as tasks. If these synchronization methods can use Async versions of .NET methods, I try to "go deeper" whenever possible.

+3
Jun 18 '14 at 23:27
source share



All Articles