簡體   English   中英

在 wpf 后面創建控件異步代碼

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM