在其阻止版本中使用方法的异步实现

时间:2015-03-03 06:56:14

标签: c# .net asynchronous async-await task-parallel-library

我创建了Stream的自定义子类,其实现为Read。 实现中使用的操作可以充分利用async API,因此我也希望提供ReadAsync实现。

这些方法共享许多类似的行为,避免代码重复的最简单方法是将逻辑保留在ReadAsync实现中,并在Read实现中使用它。这看起来像这样:

public override int Read(byte[] buffer, int offset, int count)
{
    return ReadAsync(buffer, offset, count).Result;
}

这种方法会有什么影响吗?由于Read方法应该阻塞当前线程,我认为它完全符合规范。

谢谢!

2 个答案:

答案 0 :(得分:6)

  

这种方法会有什么影响吗?

是的,这是sync over async anti-pattern,应该避免。主要原因是它很容易导致死锁

怎么可能?当您阻塞线程时,您的内部ReadAsync可能正在等待异步操作完成。如果这个线程是例如UI消息循环线程,它当前被阻止。当您的await完成时(假设您没有在内部使用ConfigureAwait(false)),当尝试将延续编组到其上时,它会陷入僵局。

编写异步代码时,会有一些代码重复,没有解决方法。尝试尽可能多地重用。例如,如果两个代码方法在开头都有同步部分,则可以将其提取到第三种方法,即异步和同步版本都将使用这种方法。

答案 1 :(得分:1)

这取决于您的Async方法的实现 - 如果它等待当前线程的某些东西会出现死锁。通常,最好不要阻止等待异步方法。