gpt4 book ai didi

c# - 下载图像时异步/等待死锁

转载 作者:太空狗 更新时间:2023-10-29 22:00:31 25 4
gpt4 key购买 nike

我正在开发 Windows Phone 8.1 应用程序。我有一个带有缩略图的新闻标题列表的屏幕。

首先,我正在发出异步 http 请求以获取 JSON 中的新闻集合(满足 NotifyTaskCompletion pattern )

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 ,即:

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.

我不知道我在哪里可以用阻塞的方式拥有这些东西。造成这种僵局的原因是什么?

如果这都是错误的方法,您是否知道更适合将缩略图下载到项目集合的模式?

感谢您的帮助。


更新 GetImage 是如何调用的:就像主题: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;
}
}
}

在 xaml 中:

<Image 
DataContext="{Binding ImagePath, Converter={StaticResource WebPathToImage}}"
Source="{Binding Result}"
Stretch="UniformToFill"
Height="79" Width="79"/>

最佳答案

首先,如果您使用的是 Windows Phone 8.1,那么建议使用命名空间 Windows.Web.Http 中的 HttpClient 而不是 System.网络.Http。在 this link 上解释了一些原因.

我的回答使用了新的 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;
}
}

我已经在示例 URL 上测试了此方法,它在 Image 控件中正确显示。

其次,为什么不让 Image 控件处理下载 BitmapImage 而无需转换器,这样您的 XAML 看起来像这样:

<Image
Source="{Binding ImagePath}"
Stretch="UniformToFill"
Height="79"
Width="79" />

这样,您的 ImagePath 就可以成为来自 Internet 和本地资源的资源路径。

关于c# - 下载图像时异步/等待死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32201667/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com