Here is a new answer for you, hopefully better than the previous one.
When you create a binding with "IsAsync" true, it accesses the Author.IconUrl property in a separate thread, but does the conversion from Uri to ImageSource to the main thread. As you have discovered, the conversion performs a DNS lookup in the main thread, causing the application to block.
Since your source is http / https, WPF automatically handles the asynchronous loading of the image source. Therefore, I suspect that all you need to do is just an asynchronous DNS lookup.
This can be automated using the attached property:
<Image my:ImageAsyncHelper.SourceUri="{Binding Author.IconUrl}" />
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; } } } }
How it works:
- When you set the attached property, it creates an instance of ImageAsyncHelper and asynchronously associates Image.Source with the ImageSource prototype of the asynchronous helper object.
- When the asynchronous binding is triggered, it calls the VerifiedUri authenticator, which checks the address available, then returns [
- If the IconUri property ever changes, the binding updates the attached property, which creates and binds the new ImageAsyncHelper so that the images are kept up to date.
Ray burns
source share