2013-10-25 99 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