我正在创建一个相册应用,我想按类别显示图片。
在正常模式下,一切正常,并显示图像。
但是,当图像数量变大(300)时,程序将挂起,并且显示时间较长。
所以我想使用异步并显示图像。
我使用了以下代码,但是什么也没有发生,并且图像不显示
int HandleFileAsync()
{
AllofItems.ForEachWithIndex((item, idx) =>
{
var cv = new CoverViewItem();
var contentImg = new Image();
contentImg.Stretch = Stretch.UniformToFill;
contentImg.Source = new BitmapImage(new Uri(item, UriKind.Absolute));
var img = new Image();
img.Source = new BitmapImage(new Uri(item, UriKind.Absolute));
//-< source >-
BitmapImage src = new BitmapImage();
src.BeginInit();
src.UriSource = new Uri(item, UriKind.Absolute);
//< thumbnail >
src.DecodePixelWidth = 160;
src.CacheOption = BitmapCacheOption.OnLoad;
//</ thumbnail >
src.EndInit();
img.Source = src;
//-</ source >-
img.Stretch = Stretch.Uniform;
img.Height = 160;
cv.Header = img;
cv.Tag = item;
cv.Content = contentImg;
cv.Selected += Cv_Selected;
cv.Deselected += Cv_Deselected;
Dispatcher.Invoke(() =>
{
cover.Items.Add(cv);
});
});
return AllofItems.Count();
}
async void Example()
{
// This method runs asynchronously.
int t = await Task.Run(() => HandleFileAsync());
Console.WriteLine("Compute: " + t);
}
private void Listbox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
AllofItems = GetFileList(@"E:\DL\newArtWork\Art\" + listbox.SelectedItem).ToArray();
cover.Items.Clear();
Example();
}
答案 0 :(得分:2)
这是xaml中的另一种选择:
<ItemsControl ItemsSource="{Binding FilesList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding IsAsync=True}"/>
<DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
这将使每个图像都在后台线程中加载并在完成后显示。如果要显示很多图像,可以添加ValueConverter来按比例缩小图像。
重点是,{Binding IsAsync=True}
完成了您需要的所有魔术,即使使用转换器,它仍然是异步的
答案 1 :(得分:0)
在循环的主体中放置try{}catch()
并检查,您肯定会在其中接受。
async void
不适用于异常处理,它是一种反模式。
Image
必须在GUI线程上创建。由于使用Task.Run
,因此从GUI线程转到.NET线程池。 Image
创建时必须例外。
将数据加载到后台线程/.NET线程池中,并使用Dispatcher.Invoke()
创建GUI对象