Asynchronous methods, typically declared as public async Task Foo()
, are crucial for concurrent operations and enhanced user experience. However, integrating them into existing synchronous codebases requires careful consideration. Let's examine several approaches.
Task.WaitAndUnwrapException
For straightforward asynchronous methods that don't rely on context synchronization (e.g., those using ConfigureAwait(false)
), Task.WaitAndUnwrapException
offers a simple solution:
var task = MyAsyncMethod(); var result = task.WaitAndUnwrapException();
This neatly handles exceptions without the extra layer of AggregateException
. However, this method is inappropriate if MyAsyncMethod
requires context synchronization.
AsyncContext.RunTask
When context synchronization is essential, AsyncContext.RunTask
provides a nested context:
var result = AsyncContext.RunTask(MyAsyncMethod).Result;
This effectively prevents deadlocks that might arise from blocking waits on tasks that don't use ConfigureAwait(false)
.
Task.Run
If AsyncContext.RunTask
is unsuitable (e.g., when asynchronous methods await UI events), offload the asynchronous method to the thread pool:
var task = Task.Run(async () => await MyAsyncMethod()); var result = task.WaitAndUnwrapException();
This approach demands that MyAsyncMethod
is thread-safe and doesn't depend on UI elements or the ASP.NET request context. Alternatively, using ConfigureAwait(false)
with Method 1 provides a viable alternative.
For a deeper understanding, consult Stephen Cleary's insightful 2015 MSDN article, "Async Programming - Brownfield Async Development".
The above is the detailed content of How Can I Call Asynchronous C# Methods Synchronously?. For more information, please follow other related articles on the PHP Chinese website!