我讀過很多帖子,人們面臨類似的問題,但他們似乎做出不適用的假設或他們的代碼根本不適用於我。我需要結合異步方法的結果。 我想要的唯一的異步是結果的組合。由於Azure服務總線一次只允許我抓取256條消息,因此我想發送多個請求以一次獲得幾個批次,並將其製作成一個列表。結合異步方法和同步返回
似乎是,如果你調用一個異步 方法要返回給調用者的假設而完成的各項工作 (即:需要長時間運行的任務)。但是,我根本不需要這個。我 想等待任務完成,然後把我的組合列表 並返回它。
首先,我不想用async標記我的調用方法。我可以,但爲什麼我應該,我無意中調用了一個同步方法,在返回給我之前恰好執行一些異步操作。
我看過使用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,但是在獲得結果之前它會退出我的方法。
謝謝!我仍然得到異步/等待的東西。我仍然不確定爲什麼WaitAll()非常簡單。我不需要await關鍵字,我不必將當前方法標記爲async。我只是創建一些任務並說WaitAll()。如果我想在突然完成任務後得到結果,我必須將當前方法標記爲異步。似乎很奇怪。 – 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)和[this](https://msdn.microsoft.com/en-us/雜誌/ gg598924.aspx)可以很好地解釋同步上下文。 – Absolom