C# 异步时还需要支持同步调用

One*_*All 4 .net c# async-await

我遇到的情况是,我们有一些由用户输入(单击按钮)运行的代码,这些代码运行一系列函数调用并生成一些数据(这是一个非常繁重的操作,需要几分钟)。我们想为此使用 Async 以便在我们执行此操作时它不会锁定 UI。

但同时我们也有一个要求,即这些功能也可以通过 API 使用,最好是同步的。

可视化/示例(伪代码):

public async void Button_Click() // from UI context
{
  await instanceOfClassA.FuncA();

  // some code
}

public async Task ClassA.FuncA()
{
  await instanceOfClassB.FuncB()

  // some code
}

public async Task ClassB.FuncB()
{
  await instanceOfClassC.SomeHeavyFunc()

  // some code
}

public async Task ClassC.SomeHeavyFunc()
{
  // some heavy calculations
}


// Also need to provide a public synchronous API function
public void SomeClass.SynchronousAPIFunc()
{
  // need to call differentInstanceOfClassB.FuncB()
}
Run Code Online (Sandbox Code Playgroud)

有没有办法让公共 API 函数在内部等待异步操作?

编辑:在这篇文章中,用户 Rachel 为这个问题提供了两个答案。两者看起来都很有趣,但我不确定哪一个会提供最少的风险/副作用。

EDIT2:我应该注意到我们使用的是 .NET v4.6.1。

提前致谢。

Gab*_*uci 7

制作只调用异步版本的方法的“同步”版本的问题在于它可能导致死锁,特别是如果调用此代码的人不知道正在发生的事情。

如果您真的想要制作同步版本,那么请按照 Microsoft 的指导编写不使用任何异步代码的全新方法。例如, for 的实现File.ReadAllLines()不使用任何与File.ReadAllLinesAsync().

如果您不想这样做,那么就不要提供方法的同步版本。让来电者决定如何处理。如果他们想同步阻塞,那么他们可以降低死锁的风险。