我正在构建一个 Windows 应用商店应用程序并同时学习 XAML。我在 http URI 上有远程图像,我想在 GridView 中显示它。
我最初的解决方案涉及使用 HttpClient
从 URI 下载图像字节数组,获取 RandomAccessStreamReference
,构造 BitmapImage
,然后将 XAML Image
控件的 source 属性设置为构造的 BitmapImage
。然而,事实证明这个解决方案相当慢(需要 1-2 秒才能获得单个图像)。
我的下一个解决方案是将原始 URI 直接绑定(bind)到 XAML Image
控件的源属性,XAML 引擎似乎会自行解析。过去需要 10 秒才能加载大约 8-10 张图像的事情突然变得即时了。
有谁知道 XAML Image
控件的默认 URI 转换器究竟如何解析远程图像数据?我的第一个解决方案完全有可能实现得不好,但差异足够大,足以激起我的好奇心。
最佳答案
假设我从 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
依次使用 BitmapDecoder
加载图像。当源是 Uri
时,BitmapDecoder
在一系列安全和健全性检查中,使用 WpfWebRequestHelper
(未记录)来请求或“下载”图像。如果生成的响应流是有效文件,它会直接将该流加载到新的 FileStream
中。
随后, native Windows 图像解码功能将接管以获取图像。另请注意,BitmapDecoder
会被缓存,因此,如果您连续加载多个图像,则无需重新初始化新 BitmapDecoder
的开销。我不能说这是否与您的性能问题有关。
总之,我猜测 WPF 内部使用的加载图像的方法是一种高度优化的方法。我还没有看过 HttpClient
的实现与简单 HttpWebRequest
的可能使用下载图像,但我怀疑您的方法的开销比内置方法的开销更大,这导致了您的性能下降。
如果您想知道我是如何破译这些信息的,我只是使用以下命令检查了 PresentationCore
程序集中的 System.Windows.Media
命名空间中的几个类一个名为 Reflector 的工具.
关于c# - 为什么将 XAML 图像源设置为 URI 比使用 HttpClient 获取图像更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13590844/