Я читал много сообщений, в которых люди сталкивались с подобными проблемами, но они, похоже, делают предположения, которые не применяются, или их код просто не работает для меня. Мне нужно совместить результаты асинхронных методов. ТОЛЬКО вещь async, которую я хочу, это объединение результатов. Поскольку Azure Service Bus позволяет мне одновременно получать 256 сообщений, я хочу отправить несколько запросов, чтобы получить сразу несколько партий и сделать их одним списком.Объединить результаты метода асинхронного и синхронного возврата
Там, кажется, предположение, что если вы вызываете метод асинхронной вы хотите вернуться к абоненту в то время как работа завершена (т.е .: некоторые давно запущенной задачи). Тем не менее, я не хочу этого вообще. I хотите подождать завершения задач, а затем взять мой объединенный список и вернуть его.
Во-первых, я не хочу отмечать мой метод вызова асинхронным способом. Я могу, но почему я должен, я обязательно использую синхронный метод, который выполняет некоторые асинхронные действия, прежде чем возвращаться ко мне.
Я видел примеры с использованием метода WhenAll(), а затем работал с результатом, но это не работает для меня. Я пробовал все разные перестановки, но он либо блокирует мое приложение, либо говорит, что задача еще не выполнена.
Вот что я в настоящее время:
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, но затем он выходит из моего метода, прежде чем получать результаты.
Спасибо! Я все еще получаю зависание асинхронного/ждущего материала. Я все еще не уверен, почему WaitAll() настолько прост. Мне не нужно ключевое слово await, и мне не нужно отмечать текущий метод async. Я просто создаю некоторые задачи и говорю WaitAll(). Если я хочу получить результаты после завершения задач, я должен пометить текущий метод как async. Кажется странным. – KingOfHypocrites
Я не знаю, почему WaitAll действительно работает. Это не должно. И задача Task.Run определенно должна работать. Используйте отладчик, чтобы узнать, в каком фрагменте кода начинается зависание. Или закомментируйте строку Task.Run и посмотрите, работает ли она; Существует какой-то соответствующий код, который вы еще не опубликовали. Отправьте еще один код. – usr
@KingOfHypocrites: WaitAll() блокирует текущий поток, чтобы дождаться завершения всех задач, что может привести к возникновению взаимоблокировки в зависимости от вашего контекста синхронизации (UI и Asp.NET). Решение usr удаляет контекст синхронизации при выполнении вашего асинхронного метода. См. [This] (http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html) и [это] (https://msdn.microsoft.com/en-us/ журнал/gg598924.aspx) для хорошего объяснения контекста синхронизации. – Absolom