繁体   English   中英

合并异步方法的结果并同步返回

[英]Combine Results from Async Method and Return Synchronously

我读过很多帖子,人们都遇到过类似的问题,但是他们似乎做出了不适用的假设,或者他们的代码根本不适合我。 我需要结合异步方法的结果。 我想要的唯一异步的是结果的组合。 由于Azure Service Bus一次只允许我抓取256条消息,因此我想发出多个请求以一次获取几批并将其放入一个列表。

似乎有一个假设,如果您正在调用异步方法,则想在工作完成时返回到调用方(即:一些长时间运行的任务)。 但是,我一点都不想要。 我想等待任务完成,然后将合并的列表返回。

首先,我不想用异步标记我的调用方法。 我可以但是为什么我应该调用同步方法,而该方法恰好在返回我之前执行一些异步操作。

我已经看到了使用WhenAll()然后使用Result的示例,但这对我不起作用。 我尝试了所有不同的排列,但是它要么锁定了我的应用程序,要么告诉我任务尚未执行。

这是我目前拥有的:

public IEnumerable<BrokeredMessage>[] GetCombinedResults()
{
            var job = () => ServiceBus.TrackerClient.ReceiveBatchAsync(BatchLimit);
            Task<IEnumerable<BrokeredMessage>> task1 = _retryPolicy.ExecuteAsync<IEnumerable<BrokeredMessage>>(job);
            Task<IEnumerable<BrokeredMessage>> task2 = _retryPolicy.ExecuteAsync<IEnumerable<BrokeredMessage>>(job);
            IEnumerable<BrokeredMessage>[] results = Task.WhenAll<IEnumerable<BrokeredMessage>>(task1, task2).Result;
            return results;
}

但是调用结果会导致其锁定。 我读过这样做可能会发生死锁,但已将此建议作为其他问题的答案。 如果我调用Task.WaitAll()而不关心结果,则这种类型的安装程序可以正常工作。 不知道为什么当我想要任务返回的结果时,这变得很难。 我尝试使用Task.Run,​​但是在获得结果之前它会退出我的方法。

您似乎对使用异步进行扇出并行处理感兴趣。 那是完全合法的事情。 不必使整个呼叫链都异步以利用扇出并行性。

您偶然发现了通常的ASP.NET死锁。 您可以使用Task.Run作为避免故障的一种简单的故障安全方法。 首先,让我们使GetCombinedResults异步以使其简单和一致:

public async Task<IEnumerable<BrokeredMessage>[]> GetCombinedResultsAsync()
{
            var job = () => ServiceBus.TrackerClient.ReceiveBatchAsync(BatchLimit);
            Task<IEnumerable<BrokeredMessage>> task1 = _retryPolicy.ExecuteAsync<IEnumerable<BrokeredMessage>>(job);
            Task<IEnumerable<BrokeredMessage>> task2 = _retryPolicy.ExecuteAsync<IEnumerable<BrokeredMessage>>(job);
            IEnumerable<BrokeredMessage>[] results = await Task.WhenAll<IEnumerable<BrokeredMessage>>(task1, task2);
            return results;
}

这种方法显然是正确的。 它不混合同步和异步。 这样称呼它:

var results = Task.Run(() => GetCombinedResultsAsync()).Result;

这样做的原因是GetCombinedResultsAsync现在无需同步上下文GetCombinedResultsAsync执行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM