异步库调用互相依赖以及如何处理?

Lia*_*iam 1 c# asp.net asynchronous task-parallel-library async-await

这是我之前发布的一个问题的后续问题.使用Task.Run调用异步方法似乎错了?

我认为承包商编写的代码是错误的,但是从提供的答案开始,我现在想知道这是否是图书馆的错误.该库公开了我需要使用的两种方法.一个返回一个"模板",一个消耗该模板的一部分(无论如何它都在我的实现中).但两者都是async返回的方法Tasks.

解释我的库有方法:

public Task<TemplateInfo> TemplateInfo(TemplateInfoRequest request);
public Task<List<EmailResult>> SendMessageTemplate(SendMessageTemplateRequest request);
Run Code Online (Sandbox Code Playgroud)

我需要这样称呼它们:

public bool SendMessage()
{
  var template = TemplateInfo(...);
  var message = //use template to create message
  var sendResponse = SendMessageTemplate(message);

   return sendResponse.Count > 0;
}
Run Code Online (Sandbox Code Playgroud)

所以第二次通话依赖于第一次.这是异步对我没有意义的地方.我不能也不想并行运行这些.我想按顺序运行它们.我希望我的方法是同步的.

我之前的问题中答案还指出:

由于您在异步方法上阻塞(您不应该这样做),因此您可能会陷入僵局.

那么如何async以这样的方式访问这些方法,即依次处理它们并返回同步结果但不会导致死锁?

i3a*_*non 5

异步不(必然)意味着并行.

您可以顺序调用两个异步方法,而不会并行运行.只需调用第一个并等待返回的任务,然后对第二个执行相同的操作.

var template = await TemplateInfo(...);
var message = //use template to create message
var sendResponse = await SendMessageTemplate(message);
Run Code Online (Sandbox Code Playgroud)

与同步代码相比,这仍然很有用,因为异步操作"正在运行"时不需要线程,因此您的线程可以在应用程序的其他部分上运行.

如果您同时调用两个并且等待返回的任务,您将(可能)并行运行:

var templateTask = TemplateInfo(...);
var sendResponseTask = SendMessageTemplate(message);
await templateTask;
await sendResponseTask;
Run Code Online (Sandbox Code Playgroud)

  • @Liam最好的选择是async一直向上.这需要更改方法调用,直到到达顶部(可以是事件处理程序,"Main"等).如果你出于某种原因无法做到这一点,那么下一个选择是根本不使用异步并且一直有同步代码.如果这不是一个选项(因为您使用的库只有异步API),那么除了阻止异步代码之外,您没有任何其他选项,然后尝试确保安全地完成它. (3认同)