I have problem with converter from Uri to BitmapImage. Uri is url of image on web. I use this converter on item in listbox.
I download image from webpage and create from this stream BitampImage
Problem is if listbox consist about 100 - 250 items, app freeze, I try call WebRequestMethod in another thread but it don’t work.
Here is root part of code:
private static BitmapImage GetImgFromAzet(int sex, Uri imgUri)
{
try
{
if (imgUri == null)
{
if (sex == (int)Sex.Man)
{
return new BitmapImage(new Uri(@"pack://application:,,,/Spirit;Component/images/DefaultAvatars/man.jpg",
UriKind.RelativeOrAbsolute));
}
else
{
return new BitmapImage(new Uri(@"pack://application:,,,/Spirit;Component/images/DefaultAvatars/woman.jpg",
UriKind.RelativeOrAbsolute));
}
}
else
{
BitmapImage image = null;
Task.Factory.StartNew(() =>
{
WebRequest webRequest = WebRequest.CreateDefault(imgUri);
webRequest.ContentType = "image/jpeg";
WebResponse webResponse = webRequest.GetResponse();
image = new BitmapImage();
image.CreateOptions = BitmapCreateOptions.None;
image.CacheOption = BitmapCacheOption.OnLoad;
image.BeginInit();
image.StreamSource = webResponse.GetResponseStream();
image.EndInit();
return image;
//((System.Action)(() =>
//{
// //webResponse.Close();
//})).OnUIThread();
});
return image;
}
}
catch (Exception)
{
//default return new BitmapImage(new Uri(PokecUrl.Avatar,UriKind.RelativeOrAbsolute)); } }
My aim is download image from web, create BitamImage object from him and return as Source of Image control, but I need avoid app freezing. Also problem is if I close webResponse it broke all code.
EDITED:
I try this:
BitmapImage image;
WebRequest req = WebRequest.CreateDefault(imgUri);
req.ContentType = "image/jpeg";
using (var res = req.GetResponse())
{
image = new BitmapImage();
image.CreateOptions = BitmapCreateOptions.None;
image.CacheOption = BitmapCacheOption.OnLoad;
image.BeginInit();
image.UriSource = imgUri;
image.StreamSource = res.GetResponseStream();
image.EndInit();
}
but somewhere must be bug, code is broken.
Any advice?
Binding converter is always executed on UI thread. So you could start other thread in Convert method but eventually (as you need feedback from this thread) you have to wait until it completes, thereby you're blocking your app.
In order to solve this problem, for example, you could use Binding.IsAsync property:
Usage in xaml (inside DataTemplate of listbox item):
EDITED
I've dived into BitmapImage class and have found out that it has pretty ctor with Uri parameter, that works asynchronously.
So you shouldn't execute WebRequest by yourself. Do just like this:
EDITED 2
Your view data class.
Helper, that executes images downloading:
When you are filling model - you should start separate thread, which will download files and set up images source.