我正在开发一个Windows Phone 8.1应用程序。我有一个屏幕,其中包含新闻标题和缩略图列表。
首先,我正在进行异步http请求以获取JSON格式的新闻集合(满足
到目前为止,它运作得非常完美。但是一旦我获取了
问题出现在以下方法中:
当第一个
到目前为止,我已经尝试使用
我还发现在主题中:Deadlock while using async await,如下所示:
当您使用
我不知道我在哪里以阻塞方式处理了这些内容。什么可能是死锁的原因?
如果这完全是错误的方法,您是否知道任何更适合下载项目集缩略图的模式?
谢谢您的帮助。
首先,我正在进行异步http请求以获取JSON格式的新闻集合(满足
NotifyTaskCompletion
模式)。NewsCategories = new NotifyTaskCompletion<ObservableCollection<NewsCategory>>(_newsService.GetNewsCategoriesAsync());
新闻类别:
public class NewsCategory : ObservableObject
{
...
public string Title { get; set; }
public ObservableCollection<News> Items { get; set; }
}
新闻:
public class News : ObservableObject
{
...
public string Title { get; set; }
public string ImagePath { get; set; }
}
到目前为止,它运作得非常完美。但是一旦我获取了
ImagePath
属性,我想下载并显示给定的图像。我在这里找到了异步解决方案:WP 8.1 Binding image from a http request - 这样当xaml获取图像路径时,它会调用一个转换器类(BinaryToImageSourceConverter
),同时使用NotifyTaskCompletion
模式。问题出现在以下方法中:
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;
}
当第一个
await
被调用时,调试器永远不会到达下一行,方法也永远不会返回。 string path
变量具有适当的内容。到目前为止,我已经尝试使用
ConfigureAwait(false)
,但在我的情况下它不起作用。我还发现在主题中:Deadlock while using async await,如下所示:
当您使用
ConfigureAwait(false)
时,您告诉程序您不关心上下文。它可以解决一些死锁问题,但通常不是正确的解决方案。正确的解决方案很可能是永远不要以阻塞方式等待任务,并始终异步。我不知道我在哪里以阻塞方式处理了这些内容。什么可能是死锁的原因?
如果这完全是错误的方法,您是否知道任何更适合下载项目集缩略图的模式?
谢谢您的帮助。
更新:GetImage
是如何调用的:就像主题中所述:WP 8.1从http请求绑定图像。
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;
}
}
}
并且在XAML中:
<Image
DataContext="{Binding ImagePath, Converter={StaticResource WebPathToImage}}"
Source="{Binding Result}"
Stretch="UniformToFill"
Height="79" Width="79"/>
GetImage
是怎么被调用的?你是使用.Result
或者.Wait
阻塞等待它吗? - Yuval Itzchakovvar responseStream = webCLient.GetStreamAsync(path).Result;
,然后报告是否仍在同一行中出现死锁问题? - Florian-Rh