K.A*_*.A. 6 .net c# asynchronous async-await windows-phone-8.1
我正在开发一个Windows Phone 8.1应用程序.我有一个屏幕,上面有一些带有缩略图的新闻标题.
首先,我正在制作异步http请求以获取JSON中的新闻集合(满足NotifyTaskCompletion模式)
NewsCategories = new NotifyTaskCompletion<ObservableCollection<NewsCategory>>(_newsService.GetNewsCategoriesAsync());
Run Code Online (Sandbox Code Playgroud)
新闻分类:
public class NewsCategory : ObservableObject
{
...
public string Title { get; set; }
public ObservableCollection<News> Items { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
新闻:
public class News : ObservableObject
{
...
public string Title { get; set; }
public string ImagePath { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
到目前为止它工作得很好,但是一旦我得到了ImagePath属性,我想下载并显示给定的图像.我找到了一个在这里异步执行的解决方案:WP 8.1绑定来自http请求的图像 - 这样当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;
}
Run Code Online (Sandbox Code Playgroud)
await调用第一行时,调试器永远不会到达下一行,并且方法永远不会返回.该string path变量有适当的内容.
到目前为止,我已尝试使用ConfigureAwait(false),但它在我的情况下不起作用.
我也在主题中发现:使用异步等待时的死锁,即:
当你使用时
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
并在xaml中:
<Image
DataContext="{Binding ImagePath, Converter={StaticResource WebPathToImage}}"
Source="{Binding Result}"
Stretch="UniformToFill"
Height="79" Width="79"/>
Run Code Online (Sandbox Code Playgroud)
首先,如果您使用的是 Windows Phone 8.1,则建议使用HttpClientfrom 命名空间Windows.Web.Http而不是 from System.Net.Http。此链接解释了一些原因。
我的答案使用新的,Windows.Web.Http.HttpClient所以你的GetImage方法可以如下所示:
private async Task<BitmapImage> GetImage(string path)
{
using (var webCLient = new Windows.Web.Http.HttpClient())
{
webCLient.DefaultRequestHeaders.Add("User-Agent", "bot");
var responseStream = await webCLient.GetBufferAsync(new Uri(path));
var memoryStream = new MemoryStream(responseStream.ToArray());
memoryStream.Position = 0;
var bitmap = new BitmapImage();
await bitmap.SetSourceAsync(memoryStream.AsRandomAccessStream());
return bitmap;
}
}
Run Code Online (Sandbox Code Playgroud)
我已经在示例 URL 上测试了此方法,它在控件中正确显示Image。
其次,为什么不让Image控件在BitmapImage没有转换器的情况下处理下载,以便您的 XAML 看起来像这样:
<Image
Source="{Binding ImagePath}"
Stretch="UniformToFill"
Height="79"
Width="79" />
Run Code Online (Sandbox Code Playgroud)
这样您ImagePath就可以成为从互联网和本地资源到资源的路径。
| 归档时间: |
|
| 查看次数: |
476 次 |
| 最近记录: |