【问题标题】:async library calls relying on each other and how to handle?相互依赖的异步库调用以及如何处理?
【发布时间】:2015-12-13 02:50:25
【问题描述】:

这是我在Calling an async method using a Task.Run seems wrong?发布的上一个问题的后续内容

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

解释我的库有方法:

public Task<TemplateInfo> TemplateInfo(TemplateInfoRequest request);
public Task<List<EmailResult>> SendMessageTemplate(SendMessageTemplateRequest request);

我需要这样称呼这些:

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

   return sendResponse.Count > 0;
}

所以第二个调用依赖于第一个。这是异步对我来说没有意义的地方。 我不能也不想并行运行这些。我想按顺序运行它们。 我希望 my 方法同步。

answer in my previous question 还声明:

因为你阻塞了一个异步方法(你不应该这样做) 你有可能会陷入僵局。

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

【问题讨论】:

  • 利亚姆你非常非常非常困惑。异步并不意味着并发。
  • @Aron:异步是并发的一种形式。但是,异步与并行不同。

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


【解决方案1】:

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

您可以按顺序调用这两个异步方法,而无需它们并行运行。只需调用第一个并 await 返回的任务,然后对第二个执行相同操作。

var template = await TemplateInfo(...);
var message = //use template to create message
var sendResponse = await SendMessageTemplate(message);

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

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

var templateTask = TemplateInfo(...);
var sendResponseTask = SendMessageTemplate(message);
await templateTask;
await sendResponseTask;

【讨论】:

  • 我建议您添加一些关于非阻塞异步 I/O 的内容,以消除顺序异步的优势。
  • 但是要添加一个await,我必须将我的方法标记为async并返回一个Task,我只想要一个同步的值。我本来打算只使用.Result,但后来我阻止了异步,不是吗?我认为我不应该这样做。我在问题中添加了详细信息。
  • 我想我很困惑,在某些时候我需要停止调用异步方法并让它同步。否则我如何让用户知道发生了什么。那么我该如何优雅地摆脱这种情况而不会“阻塞”
  • @Liam 最好的选择是一直异步。这需要更改方法调用,直到到达顶部(可以是事件处理程序,Main 等等)。如果由于某种原因您不能这样做,那么下一个选择是根本不使用异步并一直使用同步代码。如果这不是一个选项(因为您使用的库只有异步 API),那么除了阻塞异步代码并尝试确保它安全完成之外,您别无选择。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-08
  • 1970-01-01
  • 2016-05-12
  • 2017-10-04
相关资源
最近更新 更多