C# 下载图像时发生异步/等待死锁

C# 下载图像时发生异步/等待死锁,c#,.net,asynchronous,windows-phone-8.1,async-await,C#,.net,Asynchronous,Windows Phone 8.1,Async Await,我正在开发一个Windows Phone 8.1应用程序。我有一个屏幕,屏幕上有一个带有缩略图的新闻标题列表 首先,我发出异步http请求以获取JSON格式的新闻收集(满足以下条件) 到目前为止,它工作得很好,但一旦我获得ImagePath属性,我就想下载并显示给定的图像。我在这里找到了一个异步执行的解决方案:-这样,当xaml获取映像路径时,它调用一个转换器类(BinaryToImageSourceConverter),也使用NotifyTaskCompletion模式 问题出现在以下方法中:

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

首先,我发出异步http请求以获取JSON格式的新闻收集(满足以下条件)

到目前为止,它工作得很好,但一旦我获得
ImagePath
属性,我就想下载并显示给定的图像。我在这里找到了一个异步执行的解决方案:-这样,当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;
}
在xaml中:

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

尝试将GetImage调用到Task.Factory.Run以强制在另一个线程中执行任务


另外请注意,在创建位图时,您可能会遇到问题,因为位图不是在UI线程中创建的。

首先,如果您使用的是Windows Phone 8.1,则建议使用命名空间
Windows.Web.Http
中的
HttpClient
,而不是
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;
            }
        }
<Image
    Source="{Binding ImagePath}" 
    Stretch="UniformToFill" 
    Height="79" 
    Width="79" />

这样,您的
ImagePath
可以是从internet到资源的路径和本地资源。

如何调用
GetImage
?或者你用
.Result
等一下来阻止它?我已经编辑了我的文章来显示代码。我没有直接看到任何可能的错误。如果您可以对此进行一个小的、最小的复制,那会有所帮助。由于我无法复制,您是否可以尝试使用
var responseStream=webCLient.GetStreamAsync(path).Result仍在同一行中死锁,则返回报告?
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;  
        }
    }
}
<Image 
DataContext="{Binding ImagePath, Converter={StaticResource WebPathToImage}}"
Source="{Binding Result}" 
Stretch="UniformToFill" 
Height="79" Width="79"/>
        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;
            }
        }
<Image
    Source="{Binding ImagePath}" 
    Stretch="UniformToFill" 
    Height="79" 
    Width="79" />