3

由于我无法控制的原因,我需要同步调用异步方法。我正在开发一个库,它使用另一个异步工作的库,我需要从Stream类的实现中使用它。此类包含同步和异步方法,我对同步的方法感到不安:

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);
}

我一直在阅读如何同步运行异步 Task<T> 方法?,特别是这个答案,并且在@Stephen Cleary 的评论中指出该解决方案不好,因为某些 ASP.NET 部分需要一个AspNetSynchronizationContext. 我正在开发一个库,所以我不知道从哪里调用我的类。

同步调用异步方法的最安全方法是什么?

4

1 回答 1

3

Stephen Toub在他的博客中介绍了所有各种方法及其相应的缺点。

只有两种通用解决方案,但都不是理想的:

  1. 复制层中的逻辑;让您的同步方法调用库中的同步方法。(这假设该库具有同步方法和异步方法)。
  2. 阻止返回的任务,类似于您的示例代码。这假设库始终使用ConfigureAwait(false),这是您无法控制的假设。如果库是上下文无关的,那么将异步调用放入 aTask.Run并阻止该任务可能会更安全。此外,请确保在阻塞任务时解包异常,因为WaitorResult会将异常包装在AggregateException.

这两种解决方案都有一些严重的维护问题。

于 2014-02-24T12:43:12.713 回答