WPF Destination array was not long enough. Check the destination index, length, and the array's lower bounds. (Parameter 'destinationArray')

 

 

 

 private async Task LoadDataAsync()
 {
     var dir = @"../../../Images";
     if (!Directory.Exists(dir))
     {
         return;
     }
     await Task.Run(async () =>
     {
         var imgs = Directory.GetFiles(dir);
         if (imgs!=null && imgs.Any())
         {
             int imgsCount = imgs.Count();
             List<Book> booksList = new List<Book>();
             ItemsCollection=new ObservableCollection<Book>();
             for (int i = 1; i<=1000000; i++)
             {
                 booksList.Add(new Book()
                 {
                     Id=i,
                     Author=$"Author_{i}",
                     Name=$"Name_{i}",
                     Chapter=$"Chapter_{i}",
                     Summary=$"Summary_{i}",
                     Title=$"Title+_{i}",
                     Topic=$"Topic_{i}",
                     Press=$"Press_{i}",
                     ISBN=$"ISBN_{i}_{Guid.NewGuid().ToString("N")}",
                     ImgSource=GetImgSourceViaImgUrl(imgs[i%imgsCount])
                 });
                 if (i%500==0)
                 {                            
                     Application.Current?.Dispatcher.BeginInvoke(() =>
                     {
                         var tempList = booksList.ToList();
                         booksList.Clear();
                         foreach (var item in tempList)
                         {
                             ItemsCollection.Add(item);
                             ItemsCount=ItemsCollection.Count;
                         }                               
                     });
                 }
             }
         }
     });
 }

 

 

In var tempList = booksList.ToList(); throw exception as below snapshot illustrates

Destination array was not long enough. Check the destination index, length, and the array's lower bounds. (Parameter 'destinationArray')

 

 

 

image

 

 

 

The root casuse is 

That’s a race condition between background thread (adding) and UI thread (reading/clearing).
  • booksList is being mutated on the background thread.

  • At the same time, Dispatcher.BeginInvoke posts a delegate to the UI thread.

  • The UI thread may not run that delegate immediately — so by the time .ToList() executes, the booksList object may already be in an inconsistent state.

That’s a race condition between background thread (adding) and UI thread (reading/clearing).

 

 

 

Updated as below and resolve the exception

private async Task LoadDataAsync()
{
    var dir = @"../../../Images";
    if (!Directory.Exists(dir))
    {
        return;
    }
    await Task.Run(async () =>
    {
        var imgs = Directory.GetFiles(dir);
        if (imgs!=null && imgs.Any())
        {
            int imgsCount = imgs.Count();
            List<Book> booksList = new List<Book>();
            ItemsCollection=new ObservableCollection<Book>();
            for (int i = 1; i<=1000000; i++)
            {
                booksList.Add(new Book()
                {
                    Id=i,
                    Author=$"Author_{i}",
                    Name=$"Name_{i}",
                    Chapter=$"Chapter_{i}",
                    Summary=$"Summary_{i}",
                    Title=$"Title+_{i}",
                    Topic=$"Topic_{i}",
                    Press=$"Press_{i}",
                    ISBN=$"ISBN_{i}_{Guid.NewGuid().ToString("N")}",
                    ImgSource=GetImgSourceViaImgUrl(imgs[i%imgsCount])
                });
                if(i%500==0)
                {
                    var tempList = booksList.ToList();
                    booksList.Clear();                            
                    Application.Current?.Dispatcher.BeginInvoke(() =>
                    {
                        foreach (var item in tempList)
                        {
                            ItemsCollection.Add(item);
                            ItemsCount=ItemsCollection.Count;
                        }
                    });
                }
                await Task.Delay(1);
            }
        }
    });
}

 

 

Thread safer options with lock

private object objLock=new object();
private async Task LoadDataAsync()
{
    var dir = @"../../../Images";
    if (!Directory.Exists(dir))
    {
        return;
    }
    await Task.Run(async () =>
    {
        var imgs = Directory.GetFiles(dir);
        if (imgs!=null && imgs.Any())
        {
            int imgsCount = imgs.Count();
            List<Book> booksList = new List<Book>();
            ItemsCollection=new ObservableCollection<Book>();
            for (int i = 1; i<=1000000; i++)
            {
                booksList.Add(new Book()
                {
                    Id=i,
                    Author=$"Author_{i}",
                    Name=$"Name_{i}",
                    Chapter=$"Chapter_{i}",
                    Summary=$"Summary_{i}",
                    Title=$"Title+_{i}",
                    Topic=$"Topic_{i}",
                    Press=$"Press_{i}",
                    ISBN=$"ISBN_{i}_{Guid.NewGuid().ToString("N")}",
                    ImgSource=GetImgSourceViaImgUrl(imgs[i%imgsCount])
                });
                if(i%500==0)
                {
                    List<Book> tempList;
                    // safe copy on background thread
                    lock (objLock)
                    {
                        tempList = booksList.ToList();
                        booksList.Clear();
                    }
                    Application.Current?.Dispatcher.BeginInvoke(() =>
                    {
                        foreach (var item in tempList)
                        {
                            ItemsCollection.Add(item);
                            ItemsCount=ItemsCollection.Count;
                        }
                    });
                }
                await Task.Delay(1);
            }
        }
    });
}

 

 

//xaml
<Window x:Class="WpfApp71.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"
        WindowState="Maximized"
        xmlns:local="clr-namespace:WpfApp71"
        mc:Ignorable="d"
        Title="{Binding ItemsCount,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
        Height="450" Width="800">
    <Grid>
        <ListBox x:Name="lbx"
             ItemsSource="{Binding ItemsCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
             VirtualizingPanel.IsVirtualizing="True"
             VirtualizingPanel.VirtualizationMode="Recycling"
             VirtualizingPanel.ScrollUnit="Item">
            <ListBox.ItemContainerStyle>
                <Style TargetType="{x:Type ListBoxItem}">
                    <Setter Property="FontSize" Value="30"/>
                    <Setter Property="VerticalAlignment" Value="Center"/>
                    <Setter Property="Height" Value="{Binding DataContext.LbxItemHeight,
                            RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}"/>
                    <Setter Property="Width" Value="{Binding DataContext.LbxItemWidth,
                            RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}"/>
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="FontSize" Value="50"/>
                            <Setter Property="Foreground" Value="Red"/>
                        </Trigger>                        
                    </Style.Triggers>
                   
                </Style>
            </ListBox.ItemContainerStyle>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid
                         Width="{Binding DataContext.LbxItemWidth,
                        RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}"
                          Height="{Binding DataContext.LbxItemHeight,
                        RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}">
                        <Grid.Background>
                            <ImageBrush ImageSource="{Binding ImgSource}"/>
                        </Grid.Background>
                        <Grid.Resources>
                            <Style TargetType="DataGridCell">
                                <Setter Property="Width" Value="Auto"/>
                            </Style>
                            <Style TargetType="{x:Type TextBlock}">
                                <Setter Property="VerticalAlignment" Value="Center"/>
                            </Style>
                        </Grid.Resources>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                        </Grid.ColumnDefinitions>
                        <TextBlock Text="{Binding Id}" Grid.Column="0"/>
                        <TextBlock Text="{Binding Name}" Grid.Column="1"/>
                        <TextBlock Text="{Binding Author}" Grid.Column="2"/>
                        <TextBlock Text="{Binding Chapter}" Grid.Column="3"/>
                        <TextBlock Text="{Binding Summary}" Grid.Column="4"/>
                        <TextBlock Text="{Binding Title}" Grid.Column="5"/>
                        <TextBlock Text="{Binding Topic}" Grid.Column="6"/>
                        <TextBlock Text="{Binding Press}" Grid.Column="7"/>
                        <TextBlock Text="{Binding ISBN}" Grid.Column="8"/>
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>



//cs
using CommunityToolkit.Mvvm.ComponentModel;
using System.Collections.ObjectModel;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp71
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            RenderOptions.ProcessRenderMode=System.Windows.Interop.RenderMode.Default;
            var vm = new MainVM(this);
            this.DataContext=vm;
        }
    }

    public partial class MainVM : ObservableObject
    {
        private Window win;
        private ListBox lbx;
        public MainVM(Window winValue)
        {
            win= winValue;
            if (win!=null)
            {
                win.SizeChanged+=Win_SizeChanged;
            }
            //LoadDataAsyncByProgress();
            LoadDataAsync();
        }

        private void Win_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            var tempLbx = win.FindName("lbx") as ListBox;
            if (tempLbx!=null)
            {
                lbx=tempLbx;
                LbxItemHeight=lbx.ActualHeight/2;
                LbxItemWidth=lbx.ActualWidth;
            }
        }

        private object objLock=new object();
        private async Task LoadDataAsync()
        {
            var dir = @"../../../Images";
            if (!Directory.Exists(dir))
            {
                return;
            }
            await Task.Run(async () =>
            {
                var imgs = Directory.GetFiles(dir);
                if (imgs!=null && imgs.Any())
                {
                    int imgsCount = imgs.Count();
                    List<Book> booksList = new List<Book>();
                    ItemsCollection=new ObservableCollection<Book>();
                    for (int i = 1; i<=1000000; i++)
                    {
                        booksList.Add(new Book()
                        {
                            Id=i,
                            Author=$"Author_{i}",
                            Name=$"Name_{i}",
                            Chapter=$"Chapter_{i}",
                            Summary=$"Summary_{i}",
                            Title=$"Title+_{i}",
                            Topic=$"Topic_{i}",
                            Press=$"Press_{i}",
                            ISBN=$"ISBN_{i}_{Guid.NewGuid().ToString("N")}",
                            ImgSource=GetImgSourceViaImgUrl(imgs[i%imgsCount])
                        });
                        if(i%500==0)
                        {
                            List<Book> tempList;
                            // safe copy on background thread
                            lock (objLock)
                            {
                                tempList = booksList.ToList();
                                booksList.Clear();
                            }
                            Application.Current?.Dispatcher.BeginInvoke(() =>
                            {
                                foreach (var item in tempList)
                                {
                                    ItemsCollection.Add(item);
                                    ItemsCount=ItemsCollection.Count;
                                }
                            });
                        }
                        await Task.Delay(1);
                    }
                }
            });
        }

        private void PopulateItemsCollectionAndRender(List<Book> booksList)
        {
            
        }

        private async Task LoadDataAsyncByProgress()
        {
            var dir = @"../../../Images";
            if (!Directory.Exists(dir)) return;

            ItemsCollection = new ObservableCollection<Book>();

            var imgs = Directory.GetFiles(dir);
            int imgsCount = imgs.Length;

            var progress = new Progress<List<Book>>(chunks =>
            {
                foreach (var book in chunks)
                {
                    ItemsCollection.Add(book);
                }
                ItemsCount = ItemsCollection.Count;
            });

            await Task.Run(async () =>
            {
                var booksList = new List<Book>();
                for (int i = 1; i <= 1000000; i++)
                {
                    booksList.Add(new Book()
                    {
                        Id = i,
                        Author = $"Author_{i}",
                        Name = $"Name_{i}",
                        Chapter = $"Chapter_{i}",
                        Summary = $"Summary_{i}",
                        Title = $"Title+_{i}",
                        Topic = $"Topic_{i}",
                        Press = $"Press_{i}",
                        ISBN = $"ISBN_{i}_{Guid.NewGuid():N}",
                        ImgSource = GetImgSourceViaImgUrl(imgs[i % imgsCount])
                    });

                    if (i % 500 == 0)
                    {
                        var chunk = booksList.ToList();
                        booksList.Clear();
                        ((IProgress<List<Book>>)progress).Report(chunk);
                        await Task.Yield(); // let UI update
                    }
                }
            });
        }

        private ImageSource GetImgSourceViaImgUrl(string imgUrl)
        {
            BitmapImage bmi = new BitmapImage();
            if (!File.Exists(imgUrl))
            {
                return bmi;
            }
            bmi.BeginInit();
            bmi.UriSource=new Uri(imgUrl, UriKind.RelativeOrAbsolute);
            bmi.EndInit();
            if (bmi.CanFreeze)
            {
                bmi.Freeze();
            }
            return bmi;
        }

        [ObservableProperty]
        private ObservableCollection<Book> itemsCollection;

        [ObservableProperty]
        private int itemsCount;

        [ObservableProperty]
        private double lbxItemHeight;

        [ObservableProperty]
        private double lbxItemWidth;
    }


    public class Book
    {
        public int Id { get; set; }
        public string Author { get; set; }
        public string Name { get; set; }
        public string Chapter { get; set; }
        public string Summary { get; set; }
        public string Title { get; set; }
        public string Topic { get; set; }
        public string Press { get; set; }
        public string ISBN { get; set; }
        public ImageSource ImgSource { get; set; }
    }
}

 

image

 

image

 

posted @ 2025-09-06 12:03  FredGrit  阅读(10)  评论(0)    收藏  举报