如果 ImageSource 引用了无法访问的 Url,如何防止 WPF 图像被阻塞? [英] How can I keep a WPF Image from blocking if the ImageSource references an unreachable Url?

查看:17
本文介绍了如果 ImageSource 引用了无法访问的 Url,如何防止 WPF 图像被阻塞?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写 WPF 应用程序并尝试使用以下 XAML 将图像绑定到我的视图模型:

I'm writing a WPF application and trying to bind an image to my view model with the following XAML:

<Image Source="{Binding Author.IconUrl, IsAsync=True}" />

问题在于图像 URL 是由用户定义的,通常可以引用托管在内部网 Web 服务器上的图像.当 WPF 应用程序远程运行时,它会在尝试解析现在无法访问的图像时锁定.

The problem is that the image URLs are defined by users and can often refer to images hosted on intranet web servers. When the WPF application is run remotely, it locks up while trying to resolve the images that are now unreachable.

我认为IsAsync"绑定属性会导致加载发生在后台,但似乎DNS解析可能仍然发生在主线程中?

I thought the "IsAsync" binding property would cause the load to happen in the background, but it appears that the DNS resolution may still happen in the main thread?

我能做些什么来防止我的应用被锁定,即使图像无法访问?

What can I do to keep my app from locking, even if the images are unreachable?

谢谢,科里

推荐答案

这是一个新的答案,希望比我之前的答案更好.

Here is a new answer for you, hopefully better than my earlier one.

当您使用IsAsync"为真创建绑定时,它会在单独的线程上执行对 Author.IconUrl 的属性访问,但会在主线程中执行从 Uri 到 ImageSource 的转换.正如您所发现的,转换会在主线程上进行 DNS 查找,导致应用程序锁定.

When you create your binding with 'IsAsync' true, it executes the property access to Author.IconUrl on a separate thread but does the conversion from Uri to ImageSource in the main thread. As you discovered, the conversion does a DNS lookup on the main thread causing the application to lock up.

由于您的源是 http/https,WPF 将自动处理异步加载图像源.所以我怀疑你需要做的就是让 DNS 查找异步.

Since your source is http/https, WPF will automatically handle asynchronously loading the image source. So I suspect all you need to do is to make just the DNS lookup asynchronous.

这可以通过使用附加属性来自动化:

This can be automated by using an attached property:

<Image my:ImageAsyncHelper.SourceUri="{Binding Author.IconUrl}" />

其中 ImageAsyncHelper 定义为:

where ImageAsyncHelper is defined as:

public class ImageAsyncHelper : DependencyObject
{
  public static Uri GetSourceUri(DependencyObject obj) { return (Uri)obj.GetValue(SourceUriProperty); }
  public static void SetSourceUri(DependencyObject obj, Uri value) { obj.SetValue(SourceUriProperty, value); }
  public static readonly DependencyProperty SourceUriProperty = DependencyProperty.RegisterAttached("SourceUri", typeof(Uri), typeof(ImageAsyncHelper), new PropertyMetadata
  {
    PropertyChangedCallback = (obj, e) =>
    {
      ((Image)obj).SetBinding(Image.SourceProperty,
        new Binding("VerifiedUri")
        {
          Source = new ImageAsyncHelper { GivenUri = (Uri)e.NewValue },
          IsAsync = true,
        });
    }
  });

  Uri GivenUri;
  public Uri VerifiedUri
  {
    get
    {
      try
      {
        Dns.GetHostEntry(GivenUri.DnsSafeHost);
        return GivenUri;
      }
      catch(Exception)
      {
        return null;
      }

    } 
  } 
}

它的工作方式是:

  1. 当您设置附加属性时,它会创建一个 ImageAsyncHelper 实例,并将 Image.Source 异步绑定到异步助手对象的 ImageSource 属性.
  2. 当异步绑定触发时,它会调用 VerifiedUri getter 来验证地址是否可访问,然后返回 GivenUri
  3. 如果您的 IconUri 属性发生更改,则绑定会导致附加属性更新,从而创建并绑定新的 ImageAsyncHelper,以便图像保持最新.

这篇关于如果 ImageSource 引用了无法访问的 Url,如何防止 WPF 图像被阻塞?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆