Pergunta

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?

Foi útil?

Solução

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:

  1. Duplicate the logic in your layer; have your synchronous methods call the synchronous methods in the library. (This assumes that the library has synchronous methods as well as asynchronous).
  2. Block on the returned task, similar to your example code. This assumes that the library always uses 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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top