2015-12-31 107 views
11

我想找到我的項目之一的最佳實踐。這是一個典型的帶有UI的WPF應用程序,它顯示項目列表,並且有一個返回結果的數據服務。異步等待vs GetAwaiter()。GetResult()和回調

我們正在異步調用該服務,以便不阻止用戶界面。我們已經在我們面前的兩個選項:

  1. 使用異步等待關鍵字 這需要標記所有的按鈕的方法異步單擊所有服務層的方式(在客戶端類,使HTTP調用服務器)和其中的任何方法。這種方法能正常工作等,然後到處傳播異步的問題

  2. 使用awaiter和回調 在這種方法中,UI客戶端調用業務層和傳送回調到服務層,服務層包裝了HTTP調用服務器,並使用GetAwaiter()。GetResult(),當http調用完成時,調用UI客戶端傳遞的回調函數。在這種情況下,沒有方法必須標記爲異步,但不確定使用GetAwaiter()。GetAwaiter()。GetResult() );

我只是試圖找出這是一個更好的辦法,如果有一些問題有兩種方法,我應該知道的

+1

我敢肯定,第二種方法偶爾會導致死鎖。我知道,因爲我在使用Windows Universal進行開發時遇到了類似的情況。 – Felype

+0

也有例外的問題。我知道一個完整的異步實現,最後得到'AggregateException',但我不知道'GetAwaiter'方法中的異常會發生什麼。 – Eris

+0

@Eris當您等待時,您不會收到'AggregateException'。你會得到內在的異常。 'GetResult'也是一樣。 – i3arnon

回答

16

您應該使用asyncawait關鍵字一路攀升,或者你不應該使用異步。

你的第二個選項並不是非同步的。它正在調用異步操作並與task.GetAwaiter().GetResult()同步地對其進行阻止。 除了非常複雜之外,它不是異步的,可能導致死鎖。

+0

你有更多關於爲什麼會導致死鎖的背景信息?我也經歷過這種情況,但我正在尋找一些更深入的信息,說明爲什麼會發生這種情況或這是如何工作的。 –

+2

@FrederikGheysels http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html – i3arnon

+0

聽起來像很棒的建議,除非我從Azure Active Directory(TokenCache)中獲取此API需要同步操作。直到讀取緩存後才能從「BeforeAccessNotification」返回,並且在寫入緩存之前無法從「AfterAccessNotification」返回。當你被迫進入同步API並需要訪問文件時,你有什麼建議? –