2014-06-16 85 views
1

我正在做一個HttpRequest到一個Url,返回一個XML內容。所以我嘗試做一個異步請求,但在這個請求期間應用程序停止(暫停),似乎它不能得到響應(瀏覽器內的url完美工作,它返回我所期望的)。應用程序進入「等待狀態」,而HttpRequest操作

這裏是我的代碼:

public static async Task<String> getResponse(String url) 
{ 
    HttpClient httpClient = new HttpClient(); 
    HttpResponseMessage request = await httpClient.GetAsync(url); 
    String stream = await request.Content.ReadAsStringAsync(); 
    return stream; 
} 

,我藉此用:

String response = UtilityClass.getResponse(requestUrl).Result; 

任何人都可以幫我嗎?

+0

當你說你沒有迴應時,你是什麼意思?答案是空的嗎?它會拋出異常還是什麼?你得到什麼狀態碼? –

回答

2

這裏發生的事情是一個僵局。沒有太多的信息,我看你是阻塞異步操作調用

string response = UtilityClass.getResponse(requestUrl).Result 

當什麼happends是,當你awaitgetResponse,正在生成TaskAwaitable捕捉你SynchronizationContext爲了回元帥延續到相同它被稱爲的上下文。但是,當它試圖組織工作bacl到捕獲的上下文它不能,因爲Result阻塞線程。這就是爲什麼你應該never block on async code。這可以通過使用ConfigureAwait(false)它告訴TaskAwaitable不封送繼續後退,並簡單地執行當前線程調用它的固定:

public static async Task<String> getResponse(String url) 
{ 
    HttpClient httpClient = new HttpClient(); 
    HttpResponseMessage request = await httpClient.GetAsync(url).ConfigureAwait(false); 
    String stream = await request.Content.ReadAsStringAsync().ConfigureAwait(false); 
    return stream; 
} 

另一種解決方案,這是更好的海事組織,是正確使用async方法和await就可以了,而不是塊:

string response = await UtilityClass.getResponse(requestUrl) 

這需要你到async關鍵字添加到調用方法。如果你不能,也許同步http請求可能是更好的解決方案。

編輯

引述@EricLippert評論這使得這個比較容易理解:

最關鍵的事情要理解此處是result = task.Result;意味着別的什麼也不做,直到結果可用,和result = await task;意味着做了其他的事情,直到結果可用。這兩種轉Task<string>成一個字符串,而是一個塊和其他不

有很多很好的帖子解釋的基本小號異步/ AWAIT:

  1. Asynchronous Programming with Async and Await
  2. Asynchrony in C# 5 Series (Eric Lippert)
  3. Async Await Intro (Stephan Cleary)
  4. Async Await FAQ
+0

我添加的「.Result」是從方法getResponse獲取字符串結果,因爲它返回任務,我想獲取字符串..對不起,也許我有點混淆它。 我沒有找到一個同步http請求的例子:/只有異步.... – Pame1692

+0

我只是想做一個http請求並獲得流結果。 – Pame1692

+0

當你調用Task的'Result'屬性時,它會像使用同步請求一樣阻止它。添加'ConfigureAwait(false)',就像我在示例中顯示的那樣 –

相關問題