自定义控件设置来自下载流的图像源

时间:2014-01-22 07:14:31

标签: windows-phone-8

我的应用程序显示需要下载Authorization http标头的图像。因此,我创建了一个自定义控件AuthenticatedImage,用于创建带有必要标头的HttpClient,下载图像流并设置控件模板的Image控件源。

我在做线程时遇到了问题,因为我在调用bitmapImage.SetSource(stream)时遇到此异常:

A first chance exception of type 'System.NotSupportedException' occurred in System.Windows.ni.dll

Additional information: Read is not supported on the main thread when buffering is disabled.

这些是我的自定义控件的简化相关方法:

public override async void OnApplyTemplate()
{
    base.OnApplyTemplate();

    this.image = GetTemplateChild(imagePartName) as Image;

    await this.SetSource(this.Source);
}

private async Task SetSource(Uri uri)
{
    var stream = await DownloadImage(uri);

    var bitmapImage = new BitmapImage();
    bitmapImage.SetSource(stream);
    this.image.Source = bitmapImage;
}

private Task<Stream> DownloadImage(Uri uri)
{
    var httpClientHandler = new HttpClientHandler();
    var httpClient = new HttpClient(httpClientHandler);

    httpClient.DefaultRequestHeaders.Add(/* custom header */);

    return httpClient.GetStreamAsync(uri);
}

我正在寻找正确的方法。

3 个答案:

答案 0 :(得分:0)

添加fllow代码:

  

Dispatcher.BeginInvoke(()=&gt; {#Set Image Source Operator with your code#});

跨线程操作符异常。

答案 1 :(得分:0)

这是一种不同的方法。我多次使用过,这可能会对你有所帮助。

private Task<Stream> DownloadImage(string uri)
    {
      HttpWebRequest imageRequest = HttpWebRequest.CreateHttp(uri);
    imageRequest.Headers["Your Header key"] = header value;
    imageRequest.BeginGetResponse(Imageresponse, imageRequest);

    }


     private void Imageresponse(IAsyncResult asyncResult)
            {
                try
                {
                    HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
                    HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);
                    using (Stream data = response.GetResponseStream())
                    {
                        using (MemoryStream memoryStream = new MemoryStream())
                        {
                            data.CopyTo(memoryStream);
                            memoryStream.Position = 0;
                            byte[] buffer = null;
                            if (memoryStream != null && memoryStream.Length > 0)
                            {
                                BinaryReader binaryReader = new BinaryReader(memoryStream);
                                buffer = binaryReader.ReadBytes((int)memoryStream.Length);
                                Stream stream = new MemoryStream();
                                stream.Write(buffer, 0, buffer.Length);
                                stream.Seek(0, SeekOrigin.Begin);
                                Dispatcher.BeginInvoke(() =>
                                {
                                    BitmapImage bitmapImage = new BitmapImage { CreateOptions = BitmapCreateOptions.None };
                                    bitmapImage.SetSource(stream);
                                    this.image.Source = bitmapImage;
                                });
                            }

                        }
                    }
                }
                catch (Exception ex)
                {
                    ExceptionHelper.WriteLog(ex);
                }

            }

答案 2 :(得分:0)

我使用GetAsync和特定的HttpCompletionOption而不是GetStreamAsync来实现它。

httpClient.GetAsync(uri, HttpCompletionOption.ResponseContentRead);

如果我使用HttpCompletionOption.ResponseHeaderRead会发生同样的问题,所以我认为它与任务返回时响应不完全可用有关,而且它是GetStreamAsync的行为。