I need to call synchronously an asynchronous method for reasons out of my control. I'm developing a library, that uses another library that works asynchronously and I need use it from an implementation of the Stream
class. Such class contains synchronous and asynchronous methods, and I am feeling uneasy about the synchronous ones:
public override sealed int Read(byte[] buffer, int offset, int count)
{
// potential deadlock on single threaded synchronization context
return ReadAsync(buffer, offset, count).Result;
}
public override async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
return await _lib.ReadAsync(buffer,offset,count);
}
I have been reading How would I run an async Task<T> method synchronously?, in particular this answer, and in the comments @Stephen Cleary states that the solution is not good, since some ASP.NET parts expect a AspNetSynchronizationContext
. I am developing a library, so I do not know where my classes are going to be called from.
What would be the safest way of invoking an async method synchronously?
Stephen Toub covers all the various approaches with their corresponding drawbacks on his blog.
There are only two general-purpose solutions, neither of which is ideal:
ConfigureAwait(false)
, an assumption that is out of your control. If the library is context-free, then it may be safer to throw the asynchronous invocation into a Task.Run
and block on that task instead. Also, ensure you unwrap exceptions when blocking on a task, since Wait
or Result
will wrap exceptions in an AggregateException
.Both of these solutions have somewhat serious maintenance problems.