I'm developing a Windows Phone 8.1 app. I have a screen with a list of news' titles with thumbnails.
First I'm making asynchronous http request to get news collection in JSON (satisfying the NotifyTaskCompletion
pattern)
NewsCategories = new NotifyTaskCompletion<ObservableCollection<NewsCategory>>(_newsService.GetNewsCategoriesAsync());
NewsCategory:
public class NewsCategory : ObservableObject
{
...
public string Title { get; set; }
public ObservableCollection<News> Items { get; set; }
}
News:
public class News : ObservableObject
{
...
public string Title { get; set; }
public string ImagePath { get; set; }
}
So far it works perfectly, but as soon as I get the ImagePath
property, I would like to download and display the given image. I've found a solution to do it asynchronously here: WP 8.1 Binding image from a http request - so that when xaml gets the image path, it calls a converter class (BinaryToImageSourceConverter
), also using the NotifyTaskCompletion
pattern.
The problem occurs in the following method:
private async Task<BitmapImage> GetImage(string path)
{
HttpClient webCLient = new HttpClient();
var responseStream = await webCLient.GetStreamAsync(path);
var memoryStream = new MemoryStream();
await responseStream.CopyToAsync(memoryStream);
memoryStream.Position = 0;
var bitmap = new BitmapImage();
await bitmap.SetSourceAsync(memoryStream.AsRandomAccessStream());
return bitmap;
}
When the first await
is called, the debugger never reach the next line and the method never returns. The string path
variable has proper content.
So far I have tried to use ConfigureAwait(false)
, but it doesn't work in my case.
I have also found out in the topic: Deadlock while using async await , that:
When you're using
ConfigureAwait(false)
, you tell your program you dont mind about the context. It can solve some deadlocking problems, but isn't usually the right solution. The right solution is most likely never to wait for tasks in a blocking way, and being asynchronous all the way.
I don't know where I could have that stuff in a blocking way. What can be the reason for that deadlock?
And if it's all about wrong approach, do you know any pattern that would be more appropriate for downloading thumbnails to a collection of items?
Thank you for your help.
update: how is GetImage
invoked: It's like in topic: WP 8.1 Binding image from a http request
public class WebPathToImage : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value == null) return null;
return new NotifyTaskCompletion<BitmapImage>(GetImage((String)value));
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{ throw new NotImplementedException(); }
private async Task<BitmapImage> GetImage(string path)
{
using (var webCLient = new HttpClient())
{
webCLient.DefaultRequestHeaders.Add("User-Agent", "bot");
var responseStream = await webCLient.GetStreamAsync(path).ConfigureAwait(false);
var memoryStream = new MemoryStream();
await responseStream.CopyToAsync(memoryStream);
memoryStream.Position = 0;
var bitmap = new BitmapImage();
await bitmap.SetSourceAsync(memoryStream.AsRandomAccessStream());
return bitmap;
}
}
}
and in xaml:
<Image
DataContext="{Binding ImagePath, Converter={StaticResource WebPathToImage}}"
Source="{Binding Result}"
Stretch="UniformToFill"
Height="79" Width="79"/>