简体   繁体   English

为什么将 XAML 图像源设置为 URI 比使用 HttpClient 获取图像更快?

[英]Why is setting a XAML Image Source to URI faster than using HttpClient to get the Image?

I'm building a Windows Store App and learning XAML at the same time.我正在构建一个 Windows 应用商店应用程序并同时学习 XAML。 I have remote images at a http URI that I want to show in a GridView.我想在 GridView 中显示的 http URI 上有远程图像。

My original solution involved using HttpClient to download the image byte array from the URI, get a RandomAccessStreamReference , construct a BitmapImage , and then set the XAML Image control's source property to the constructed BitmapImage .我的原始解决方案涉及使用HttpClient从 URI 下载图像字节数组,获取RandomAccessStreamReference ,构造BitmapImage ,然后将 XAML Image控件的 source 属性设置为构造的BitmapImage However, this solution proved to be rather slow (1-2 full seconds to get a single image).然而,这个解决方案被证明是相当慢的(1-2 整秒才能获得单个图像)。

My next solution was to bind the raw URI directly to the XAML Image control's source property directly, which the XAML engine seems to take upon itself to resolve.我的下一个解决方案是将原始 URI 直接绑定到 XAML Image控件的源属性,XAML 引擎似乎自行解决。 What used to take 10 seconds to load about 8-10 images suddenly was instant.过去需要 10 秒才能加载大约 8-10 张图像突然变成了即时。

Does anyone know how exactly the default URI converter for the XAML Image control resolves the remote image data?有谁知道 XAML Image控件的默认 URI 转换器究竟是如何解析远程图像数据的? It's entirely possible that my first solution was just poorly implemented, but the discrepancy is large enough to pique my curiosity.我的第一个解决方案完全有可能只是实施得很差,但差异大到足以激起我的好奇心。

Assuming I've found the right piece of code from the ImageSourceConverter class, when you specify the source as a string, the converter is attempting to do this:假设我从ImageSourceConverter类中找到了正确的一段代码,当您将源指定为字符串时,转换器会尝试执行以下操作:

    if (((value is string) && !string.IsNullOrEmpty((string) value)) || (value is Uri))
    {
        UriHolder uriFromUriContext = TypeConverterHelper.GetUriFromUriContext(context, value);
        return BitmapFrame.CreateFromUriOrStream(uriFromUriContext.BaseUri, uriFromUriContext.OriginalUri, null, BitmapCreateOptions.None, BitmapCacheOption.Default, null);
    }

BitmapFrame in turn uses a BitmapDecoder to load the image. BitmapFrame依次使用BitmapDecoder加载图像。 When the source is a Uri , the BitmapDecoder , amid a bunch of security and sanity checks, uses a WpfWebRequestHelper (undocumented) to request or "download" the image.当源是UriBitmapDecoder在一堆安全性和完整性检查中使用WpfWebRequestHelper (未记录)来请求或“下载”图像。 If the resulting response stream is a valid file, it directly loads the stream into a new FileStream .如果生成的响应流是有效文件,它会直接将流加载到新的FileStream

Following that, native Windows image decoding functionality takes over to get you your image.之后,本机 Windows 图像解码功能将接管您的图像。 Also note that the BitmapDecoder gets cached, so if you're loading multiple images in a row, you don't have the overhead of re-initializing a new BitmapDecoder .另请注意, BitmapDecoder会被缓存,因此如果您连续加载多个图像,则不会有重新初始化新BitmapDecoder的开销。 Whether that had anything to do with your performance issue I can't say.我不能说这是否与您的性能问题有关。

In conclusion, I'm guessing that the method WPF uses internally to load images is a highly optimized approach at doing so.总之,我猜测 WPF 在内部用于加载图像的方法是一种高度优化的方法。 I have not looked at the implementation of the HttpClient vs. the likely use of a simple HttpWebRequest to download the image, but I suspect that the overhead of your method was more than that of the built-in method and is what contributed to your slower performance.我还没有研究过HttpClient的实现与可能使用简单的HttpWebRequest来下载图像,但我怀疑您的方法的开销比内置方法的开销多,这也是导致您速度变慢的原因表现。

If you're wondering how I was able to decipher this information, I simply inspected a few classes within the System.Windows.Media namespace in the PresentationCore assembly using a tool called Reflector .如果您想知道我是如何破译这些信息的,我只是使用名为Reflector的工具检查了PresentationCore程序集中System.Windows.Media命名空间中的几个类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM