Task run should be necessary to load the image not in the UI Thread, that's correct. Also it look like you have to add this line to your code, to force immediate caching the image to memory:
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
Example to your code:
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.UriSource = new Uri(XDocument.SelectSingleNode("Launcher/News").Attributes["picture_url"].Value, UriKind.Absolute);
bitmapImage.EndInit();
Hopes this helps and here are the link were I have found it:Load a large BitmapImage asynchronously.
Here are a small example to try it:
// XAML-Code (MainWindow.xaml)
<Window x:Class="WpfAppNet.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:local="clr-namespace:WpfAppNet"
xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
mc:Ignorable="d"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
Title="MainWindow" Height="450" Width="800">
<Grid>
<StackPanel>
<Image Source="{Binding ImageSource}" />
<Button Content="Load image"
Command="{Binding LoadImageCommand}"
CommandParameter="{Binding ElementName=MyImage}"/>
</StackPanel>
</Grid>
</Window>
// Code-Behind (MainWindow.xaml.cs)
namespace WpfAppNet
{
/// <summary>
/// Interaktionslogik für MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainWindowViewModel();
}
}
public class MyApplicationList
{
public bool IsSelected { get; set; }
public string ApplicationName { get; set; }
}
}
// View-Model Code (MainWindowViewModel.cs)
namespace WpfAppNet
{
public class MainWindowViewModel : INotifyPropertyChanged
{
public ICommand LoadImageCommand { get; set; }
public ImageSource ImageSource { get; set; }
public MainWindowViewModel()
{
LoadImageCommand = new ActionCommand(LoadImageExecute);
}
private async void LoadImageExecute(object o)
{
try
{
var getImg = await LoadImg();
ImageSource = getImg;
NotifyPropertyChanged("ImageSource");
}
catch (Exception exception)
{
Console.WriteLine(exception);
}
}
private async Task<BitmapImage> LoadImg()
{
return await Task.Run(() =>
{
BitmapImage bi = new BitmapImage();
// Begin initialization.
bi.BeginInit();
// Set properties.
bi.CacheOption = BitmapCacheOption.OnLoad;
bi.UriSource = new Uri(yourImageName, UriKind.Absolute);
bi.EndInit();
bi.Freeze();
return bi;
});
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
Whit this example I hope you will get your expected result and can implement it to your code.