2013-10-25 96 views
4

我有兩個我的WP8應用程序中有一個相同的方法。給定相同的url和相同的設備,該方法適用於一個應用程序,但不適用於其他應用程序。在失敗的應用程序中,GetAsync在被調用後掛起。沒時間了,沒有例外。HttpClient GetAsync掛起

這是有問題的方法。

private async Task<Byte[]> DownloadData(string uri) 
    { 
     byte[] myDataBuffer = null; 
     var newUri = new Uri(uri, UriKind.Absolute); 
     var myWebClient = new HttpClient(); 

     var response = await myWebClient.GetAsync(newUri); 
     if (response.Content.Headers.ContentType.MediaType == "text/plain" 
      || response.Content.Headers.ContentLength < 200) 
     { 
      throw new Exception(await response.Content.ReadAsStringAsync()); 
     } 
     myDataBuffer = await response.Content.ReadAsByteArrayAsync(); 
     return myDataBuffer; 
    } 

這種情況每次都發生在一個特定的應用程序上,而不是其他的。相同的設備。有沒有人經歷過這種行爲?該網址是有效的,代碼是相同的。有沒有可能影響這個項目的項目設置?我在失敗的應用程序的另一部分使用HttpClient,它在那裏工作。

我可以更改代碼以使用HttpWebRequest並且工作正常。只是不是HttpClient。

我剛剛發現,如果我將該方法複製到我的button_click處理程序中,它也可以在那裏使用。這個方法在一個單獨的類中有問題嗎?這對我來說似乎很奇怪。

更新

什麼似乎要打破它的異步方法調用它多層。在課堂上,我有

public override byte[] GetImageData(string imageUri) 
    { 
     return GetImageDataAsync(imageUri).Result; 
    } 

    public async Task<byte[]> GetImageDataAsync(string imageUri) 
    { 
     return await DownloadData(imageUri); 
    } 
從我button_click處理

,我打電話GetImageData(uri)。如果我將其更改爲await GetImageDataAsync(uri)它可以工作。

Result不是GetImageData中引用的正確屬性嗎?

這是一個測試網址 「http://www.rei.com/pix/common/REI_logo.gif

+1

。結果塊,直到任務返回一個值。這不是'異步'的問題,它是你的代碼故意阻止。無論如何,大多數MVVM框架可以處理異步方法,所以你不需要調用'.Result'。你在用什麼框架? –

回答

11

Calling Result or Wait can cause deadlocks,因爲我在我的博客解釋。

解決此問題的正確方法是使用await。我假設您想同步阻止的原因有很多,但最好使用await並找到使其在代碼中可行的方法。

+0

正確,你可以看到我正在使用'GetImageDataAsync'等待。我使用的接口定義了非異步'GetImageData',所以我想我會很聰明,並從中調用我的異步版本,但這是炸彈的地方。 – earthling

+3

@earthling如果你真的需要有一個同步版本,那麼'返回Task.Run(()=> GetImageDataAsync(imageUri))。Result;'應該工作。但它否定了使用異步方法的所有優點,這就是爲什麼它不是一個好主意(尤其是在GUI應用程序中,這可能會凍結UI一段時間)。 – svick