如果ImageSource引用无法访问的Url,如何阻止WPF图像阻止?

Cor*_*ien 7 dns wpf image

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

<Image Source="{Binding Author.IconUrl, IsAsync=True}" />
Run Code Online (Sandbox Code Playgroud)

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

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

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

谢谢,科里

Ray*_*rns 10

这是给你的新答案,希望比我早些时候更好.

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

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

这可以通过使用附加属性自动执行:

<Image my:ImageAsyncHelper.SourceUri="{Binding Author.IconUrl}" />
Run Code Online (Sandbox Code Playgroud)

其中ImageAsyncHelper定义为:

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;
      }

    } 
  } 
}
Run Code Online (Sandbox Code Playgroud)

这种方式的工作原理是:

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