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}" />
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.
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?
Thanks, Corey
Here is a new answer for you, hopefully better than my earlier one.
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.
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}" />
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;
}
}
}
}
The way this works is:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With