[英]Create control asynchronous code behind wpf
我正在創建一個照片庫應用程序,我想按類別顯示圖片。
在正常模式下,一切正常並顯示圖像。
但是當圖像數量變大(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();
}
這是 xaml 中的另一種選擇:
<ItemsControl ItemsSource="{Binding FilesList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding IsAsync=True}"/>
<DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
這將使每個圖像在后台線程中加載並在完成后顯示。 如果你想顯示很多圖像,你可以添加一個 ValueConverter 來縮小圖像。
重點是, {Binding IsAsync=True}
完成您需要的所有魔法,即使使用轉換器,它仍然是異步的
將try{}catch()
放入循環體並檢查,您肯定會在那里接受。
async void
不利於異常處理,它是一種反模式。
Image
必須在 GUI 線程上創建。 由於您使用Task.Run
您從 GUI 線程轉到 .NET 線程池。 例外必須是Image
創建。
在后台線程/.NET 線程池中加載數據並使用Dispatcher.Invoke()
創建 GUI 對象
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.