Kin*_*tes 1 c# asynchronous azure async-await
我读过许多人们遇到类似问题的帖子,但他们似乎做出了不适用的假设,或者他们的代码根本不适用于我.我需要结合异步方法的结果.我想要的唯一的异步是结果的组合.由于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;
}
Run Code Online (Sandbox Code Playgroud)
但调用结果会导致锁定.我已经读过这样做会发生死锁但是已经将其作为其他问题的答案.如果我调用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;
}
Run Code Online (Sandbox Code Playgroud)
这种方法显然是正确的.它不会混合同步和异步.这样称呼它:
var results = Task.Run(() => GetCombinedResultsAsync()).Result;
Run Code Online (Sandbox Code Playgroud)
这样做的原因是GetCombinedResultsAsync
现在没有同步上下文.
归档时间: |
|
查看次数: |
1251 次 |
最近记录: |