473,407 Members | 2,320 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,407 software developers and data experts.

Live update stocks and prices from stocks markets

I've wpf application, where I load large data (into Wpf DataGrid) and handle multiple events per 1-5 seconds..

I have a performance issue with datagrid - rendering takes too long and freezes my app until it's all rendered.

QuestionTester.View.QuestionView:

Expand|Select|Wrap|Line Numbers
  1. <UserControl x:Class="QuestionTester.View.QuestionView"
  2.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
  5.              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
  6.              xmlns:local="clr-namespace:QuestionTester.View"
  7.              mc:Ignorable="d"
  8.              xmlns:Converters="clr-namespace:QuestionTester.Converters"
  9.              d:DesignHeight="450" d:DesignWidth="800">
  10.     <UserControl.Resources>
  11.         <Converters:FromDateConverter x:Key="FromDateConv"/>
  12.         <Converters:ToDateConverter x:Key="ToDateConv"/>
  13.         <Converters:ToTimeConverter x:Key="ToTimeConv"/>
  14.     </UserControl.Resources>
  15.     <Grid>
  16.         <Grid.RowDefinitions>
  17.             <RowDefinition Height="20"/>
  18.             <RowDefinition Height="*"/>
  19.         </Grid.RowDefinitions>
  20.         <TextBlock Grid.Row="0" Text="{Binding RecordsCount}"/>
  21.         <DataGrid
  22.             Grid.Row="1"
  23.             ItemsSource="{Binding Models}"
  24.             IsReadOnly="True" 
  25.             AutoGenerateColumns="False" 
  26.             SnapsToDevicePixels="False"
  27.             VirtualizingStackPanel.IsVirtualizing="True"
  28.             VirtualizingStackPanel.VirtualizationMode="Recycling" 
  29.             EnableRowVirtualization="True" 
  30.             MaxWidth="2560" 
  31.             MaxHeight="1600">
  32.             <DataGrid.Columns>
  33.                 <DataGridTemplateColumn Header="CreationTime" ToolTipService.ToolTip="CreationTime">
  34.                     <DataGridTemplateColumn.CellTemplate>
  35.                         <DataTemplate>
  36.                             <StackPanel Margin="4,0,0,0"  FlowDirection="LeftToRight"  VerticalAlignment="Center">
  37.                                 <ToolTipService.ToolTip>
  38.                                     <TextBlock Text="{Binding Path=CreationTime, Converter={StaticResource ToTimeConv}}"/>
  39.                                 </ToolTipService.ToolTip>
  40.                                 <TextBlock HorizontalAlignment="Left" Text="{Binding Path=CreationTime, Converter={StaticResource ToTimeConv}}"/>
  41.                             </StackPanel>
  42.                         </DataTemplate>
  43.                     </DataGridTemplateColumn.CellTemplate>
  44.                 </DataGridTemplateColumn>
  45.                 <DataGridTemplateColumn Header="StartDate" ToolTipService.ToolTip="StartDate">
  46.                     <DataGridTemplateColumn.CellTemplate>
  47.                         <DataTemplate>
  48.                             <StackPanel Margin="4,0,0,0"  FlowDirection="LeftToRight"  VerticalAlignment="Center">
  49.                                 <ToolTipService.ToolTip>
  50.                                     <TextBlock Text="{Binding Path=StartDate, Converter={StaticResource FromDateConv}}"/>
  51.                                 </ToolTipService.ToolTip>
  52.                                 <TextBlock HorizontalAlignment="Left" Text="{Binding Path=StartDate, Converter={StaticResource FromDateConv}}"/>
  53.                             </StackPanel>
  54.                         </DataTemplate>
  55.                     </DataGridTemplateColumn.CellTemplate>
  56.                 </DataGridTemplateColumn>
  57.                 <DataGridTemplateColumn Header="EndDate" ToolTipService.ToolTip="EndDate">
  58.                     <DataGridTemplateColumn.CellTemplate>
  59.                         <DataTemplate>
  60.                             <StackPanel Margin="4,0,0,0"  FlowDirection="LeftToRight"  VerticalAlignment="Center">
  61.                                 <ToolTipService.ToolTip>
  62.                                     <TextBlock Text="{Binding Path=EndDate, Converter={StaticResource ToDateConv}}"/>
  63.                                 </ToolTipService.ToolTip>
  64.                                 <TextBlock HorizontalAlignment="Left" Text="{Binding Path=EndDate, Converter={StaticResource ToDateConv}}"/>
  65.                             </StackPanel>
  66.                         </DataTemplate>
  67.                     </DataGridTemplateColumn.CellTemplate>
  68.                 </DataGridTemplateColumn>
  69.                 <DataGridTextColumn Header="Guid" Binding="{Binding Path=Guid}"/>
  70.                 <DataGridTextColumn Header="Key" Binding="{Binding Path=Key}"/>
  71.                 <DataGridTextColumn Header="Field" Binding="{Binding Path=Field}"/>
  72.                 <DataGridTextColumn Header="Field1" Binding="{Binding Path=Field1}"/>
  73.                 <DataGridTextColumn Header="Field2" Binding="{Binding Path=Field2}"/>
  74.             </DataGrid.Columns>
  75.         </DataGrid>
  76.     </Grid>
  77. </UserControl>
Expand|Select|Wrap|Line Numbers
  1. public partial class QuestionView : UserControl
  2. {
  3.     QuestionViewModel _vm;
  4.     public QuestionView()
  5.     {
  6.         InitializeComponent();
  7.         _vm = new QuestionViewModel(TaskScheduler.FromCurrentSynchronizationContext());
  8.         DataContext = _vm;
  9.     }
  10. }
QuestionModel:

Expand|Select|Wrap|Line Numbers
  1.  public class QuestionModel
  2. {
  3.     public static Random _rand = new Random();
  4.     public DateTime StartDate { get; set; }
  5.     public DateTime EndDate { get; set; }
  6.     public DateTime CreationTime{ get; set; }
  7.     public Guid Guid { get; set; }
  8.     public string Key { get; set; }
  9.     public int Field { get; set; }
  10.     public long Field1 { get; set; }
  11.     public double Field2 { get; set; }
  12.     public QuestionModel(int num)
  13.     {
  14.         Key = $"key_{num}";
  15.         Field = _rand.Next(1000000);
  16.         Field1 = _rand.Next(1000000);
  17.         Field2 = _rand.Next(1000000);
  18.         Guid = Guid.NewGuid();
  19.         CreationTime = DateTime.Now;
  20.         if (num % 2 == 0)
  21.         {
  22.             StartDate = DateTime.Now.AddDays(-1);
  23.             EndDate = DateTime.Now.AddDays(1);
  24.         }
  25.         if (num % 10 == 0)
  26.         {
  27.             StartDate = DateTime.Now.AddDays(-100);
  28.             EndDate = DateTime.Now.AddDays(100);
  29.         }
  30.         else
  31.         {
  32.             StartDate = DateTime.Now;
  33.             EndDate = DateTime.Now;
  34.         }
  35.     }
  36.     public override string ToString()
  37.     {
  38.         return $"CreationTime:{CreationTime}";
  39.     }
  40. }
QuestionViewModel:

Expand|Select|Wrap|Line Numbers
  1. public class QuestionViewModel : NotificationBase, IUpdateTotalItems, IDisposable
  2. {
  3.     const int RAND = 10000000;
  4.     static Random _rand = new Random();
  5.     const int LENGTH = 1000;
  6.     public BulkObservableCollection<QuestionModel> Models { get; }// = new BulkObservableCollection<QuestionModel>();
  7.     TaskScheduler _currentcontext;
  8.     Guid _cancelToken;
  9.     HashSet<Guid> _cancelTokensDict = new HashSet<Guid>();
  10.     DispatcherTimer _dispatcherUpdateTimer;
  11.     Thread _thread;
  12.     public QuestionViewModel(TaskScheduler currentcontext)
  13.     {
  14.         _currentcontext = currentcontext;
  15.         _cancelToken = Guid.NewGuid();
  16.         Models = new BulkObservableCollection<QuestionModel>(_cancelToken, ref _cancelTokensDict, this);
  17.  
  18.         _dispatcherUpdateTimer = new DispatcherTimer(DispatcherPriority.Background);
  19.         _dispatcherUpdateTimer.Interval = TimeSpan.FromMilliseconds(1000);
  20.         _dispatcherUpdateTimer.Tick += _dispatcherUpdateTimer_Tick;
  21.         _dispatcherUpdateTimer.Start();
  22.         QuestionModel[] array = new QuestionModel[LENGTH];
  23.         for (int i = 0; i < LENGTH; i++)
  24.         {
  25.             int indx = _rand.Next(RAND);
  26.             array[i] = new QuestionModel(indx);
  27.         }
  28.         Models.AddRange(array);
  29.         Models.LoadingFinished();
  30.         _thread = new Thread(() =>
  31.         {
  32.             while (!_cancelTokensDict.Contains(_cancelToken))
  33.             {
  34.                 QuestionModel[] arrayThread = new QuestionModel[LENGTH];
  35.                 for (int i = 0; i < LENGTH; i++)
  36.                 {
  37.                     int indx = _rand.Next(RAND);
  38.                     arrayThread[i] = new QuestionModel(indx);
  39.                 }
  40.                 Task.Factory.StartNew(() =>
  41.                 {
  42.                     try
  43.                     {
  44.                         for (int i = 0; i < arrayThread.Length; i++)
  45.                         {
  46.                             Models.Enqueue(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, arrayThread[i], 0));
  47.                         }
  48.                        // Models.AddRange(arrayThread);
  49.                     }
  50.                     catch (Exception)
  51.                     {
  52.                         throw;
  53.                     }
  54.                 }, CancellationToken.None, TaskCreationOptions.None, _currentcontext);
  55.                 Thread.Sleep(1000);
  56.             }
  57.         });
  58.         _thread.IsBackground = true;
  59.         _thread.Start();
  60.     }
  61.  
  62.  
  63.     private int Comparison(QuestionModel a, QuestionModel b)
  64.     {
  65.         if (a == null)
  66.             return 1;
  67.         if (b == null)
  68.             return -1;
  69.         var comprand = b.CreationTime.CompareTo(a.CreationTime);
  70.         return comprand;
  71.     }
  72.  
  73.     private void _dispatcherUpdateTimer_Tick(object sender, EventArgs e)
  74.     {
  75.         if (Models.IsLoading)
  76.             return;
  77.  
  78.         Models.Refresh();
  79.     }
  80.  
  81.     int _recordsCound;
  82.     public int RecordsCount
  83.     {
  84.         get => _recordsCound;
  85.         set
  86.         {
  87.             if (_recordsCound != value)
  88.             {
  89.                 _recordsCound = value;
  90.                 OnPropertyChanged("RecordsCount");
  91.             }
  92.         }
  93.     }
  94.  
  95.     public void UpdateTotalItems(int count)
  96.     {
  97.         RecordsCount = count;
  98.     }
  99.  
  100.     bool _isDisposed = false;
  101.     public void Dispose()
  102.     {
  103.         if (!_isDisposed)
  104.         {
  105.             _isDisposed = true;
  106.             lock (_cancelTokensDict)
  107.             {
  108.                 _cancelTokensDict.Add(_cancelToken);
  109.             }
  110.             if (_thread != null)
  111.             {
  112.                 try
  113.                 {
  114.                     _thread.Join();
  115.                 }
  116.                 catch
  117.                 {
  118.                 }
  119.                 _thread = null;
  120.             }
  121.             if (_dispatcherUpdateTimer != null)
  122.             {
  123.                 _dispatcherUpdateTimer.Stop();
  124.                 _dispatcherUpdateTimer.Tick -= _dispatcherUpdateTimer_Tick;
  125.                 _dispatcherUpdateTimer = null;
  126.             }
  127.         }
  128.     }
  129. }
Converters:

Expand|Select|Wrap|Line Numbers
  1.  public class ToTimeConverter : IValueConverter
  2. {
  3.     public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  4.     {
  5.         if (value == null)
  6.             return null;
  7.         DateTime? date = (DateTime)value;
  8.         if (date.HasValue)
  9.         {
  10.             return date.Value.ToString("HH:mm:ss:fff");
  11.         }
  12.         return null;
  13.     }
  14.  
  15.     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  16.     {
  17.         throw new NotImplementedException();
  18.     }
  19. }
  20. public class ToDateConverter : IValueConverter
  21. {
  22.     public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  23.     {
  24.         if (value == null)
  25.             return null;
  26.         DateTime? date = (DateTime)value;
  27.         if (date.HasValue)
  28.         {
  29.             if (date.Value.Date == DateTime.Now.Date)
  30.             {
  31.                 return "Today";
  32.             }
  33.             else if (date.Value.Date.Date == DateTime.Now.Date.AddDays(1))
  34.             {
  35.                 return "Tomorrow";
  36.             }
  37.             return date.Value.Date.ToShortDateString();
  38.         }
  39.         return null;
  40.     }
  41.  
  42.     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  43.     {
  44.         throw new NotImplementedException();
  45.     }
  46. }
  47. public class FromDateConverter : IValueConverter
  48. {
  49.     public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  50.     {
  51.         if (value == null)
  52.             return null;
  53.         DateTime? date = (DateTime)value;
  54.         if (date.HasValue)
  55.         {
  56.             if (date.Value.Date == DateTime.Now.Date)
  57.             {
  58.                 return "Today";
  59.             }
  60.             else if (date.Value.Date.Date == DateTime.Now.Date.AddDays(-1))
  61.             {
  62.                 return "Yesterday";
  63.             }
  64.             return date.Value.Date.ToShortDateString();
  65.         }
  66.         return null;
  67.     }
  68.  
  69.     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  70.     {
  71.         throw new NotImplementedException();
  72.     }
  73. }
BulkObservableCollection:

Expand|Select|Wrap|Line Numbers
  1.   public class BulkObservableCollection<T> : IDisposable, INotifyCollectionChanged, INotifyPropertyChanged, IEnumerable<T>
  2. {
  3.     ConcurrentQueue<NotifyCollectionChangedEventArgs> _losts = new ConcurrentQueue<NotifyCollectionChangedEventArgs>();
  4.     Guid? _cancelToken = null;
  5.     private HashSet<Guid> _cancelTokensDict = null;
  6.     bool _isInAddRange = false;
  7.     bool _isLoading = true;
  8.     public bool IsLoading
  9.     {
  10.         get
  11.         {
  12.             lock (_locker)
  13.             {
  14.                 return _isLoading;
  15.             }
  16.         }
  17.     }
  18.     const string COUNT = "Count";
  19.     const string ITEMS = "Item[]";
  20.     public event NotifyCollectionChangedEventHandler CollectionChanged;
  21.     public event PropertyChangedEventHandler PropertyChanged;
  22.     List<T> _items = new List<T>();
  23.     IUpdateTotalItems _updateTotalItems = null;
  24.     public int Count => _items.Count;
  25.  
  26.     public BulkObservableCollection()
  27.     {
  28.     }
  29.  
  30.     public BulkObservableCollection(Guid cancelToken, ref HashSet<Guid> cancelTokensDict, IUpdateTotalItems updateTotalItems = null)
  31.     {
  32.         _cancelToken = cancelToken;
  33.         _cancelTokensDict = cancelTokensDict;
  34.         _updateTotalItems = updateTotalItems;
  35.     }
  36.  
  37.     readonly object _locker = new object();
  38.     public void LoadingFinished()
  39.     {
  40.         lock (_locker)
  41.         {
  42.             _isLoading = false;
  43.             BeginUpdate();
  44.         }
  45.     }
  46.  
  47.     public void Refresh()
  48.     {
  49.         EndUpdate();
  50.         UpdateTotalItems(_items.Count);
  51.         BeginUpdate();
  52.     }
  53.  
  54.     #region INotifyPropertyChanged
  55.  
  56.     private void OnPropertyChanged(string propertyName)
  57.     {
  58.         if (_isDispose)
  59.             return;
  60.         if (!_isInAddRange)
  61.         {
  62.             try
  63.             {
  64.                 var ev = this.PropertyChanged;
  65.                 if (ev != null)
  66.                 {
  67.                     ev(this, new PropertyChangedEventArgs(propertyName));
  68.                 }
  69.             }
  70.             catch (Exception ex)
  71.             {
  72.                 Trace.WriteLine($"OnPropertyChanged:: Error on FirePropertyChanged propertyName = {propertyName}, Error: {ex.Message}");
  73.             }
  74.         }
  75.     }
  76.  
  77.     #endregion INotifyPropertyChanged
  78.  
  79.     #region INotifyCollectionChanged
  80.  
  81.     private void OnCollectionChanged(NotifyCollectionChangedAction action, object item, int index)
  82.     {
  83.         if (_isDispose)
  84.             return;
  85.         OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, item, index));
  86.     }
  87.  
  88.     private void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
  89.     {
  90.         if (_isDispose)
  91.             return;
  92.         if (!_isInAddRange)
  93.         {
  94.             try
  95.             {
  96.                 var ev = this.CollectionChanged;
  97.                 if (ev != null)
  98.                 {
  99.                     ev(this, e);
  100.                 }
  101.             }
  102.             catch (Exception ex)
  103.             {
  104.                 Trace.WriteLine($"OnPropertyChanged:: Error on CollectionChanged Error: {ex.Message}");
  105.             }
  106.         }
  107.     }
  108.  
  109.     #endregion INotifyCollectionChanged
  110.  
  111.     #region Add 
  112.  
  113.     public void Add(T item)
  114.     {
  115.         if (_isDispose)
  116.             return;
  117.         if (_cancelTokensDict != null && _cancelToken.HasValue && _cancelTokensDict.Contains(_cancelToken.Value))
  118.             return;
  119.        // int index = _items.Count;
  120.         InsertItem(0, item);
  121.     }
  122.  
  123.     public void Insert(int index, T item)
  124.     {
  125.         if (_isDispose)
  126.             return;
  127.         if (_cancelTokensDict != null && _cancelToken.HasValue && _cancelTokensDict.Contains(_cancelToken.Value))
  128.             return;
  129.         InsertItem(index, item);
  130.     }
  131.  
  132.     private void InsertItem(int index, T item)
  133.     {
  134.         if (_isDispose)
  135.             return;
  136.         if (_cancelTokensDict != null && _cancelToken.HasValue && _cancelTokensDict.Contains(_cancelToken.Value))
  137.             return;
  138.         _items.Insert(index, item);
  139.         OnPropertyChanged(COUNT);
  140.         OnPropertyChanged(ITEMS);
  141.         OnCollectionChanged(NotifyCollectionChangedAction.Add, item, index);
  142.     }
  143.  
  144.     public void AddRange(T[] array)
  145.     {
  146.         if (_isDispose)
  147.             return;
  148.         if (_cancelTokensDict != null && _cancelToken.HasValue && _cancelTokensDict.Contains(_cancelToken.Value))
  149.             return;
  150.         if (array == null)
  151.             throw new ArgumentNullException("array");           
  152.         BeginUpdate();
  153.         for (int i = 0; i < array.Length; i++)
  154.         {
  155.             if (_cancelTokensDict != null && _cancelToken.HasValue && _cancelTokensDict.Contains(_cancelToken.Value))
  156.                 break;
  157.             var item = array[i];
  158.             if (_cancelTokensDict != null && _cancelToken.HasValue && _cancelTokensDict.Contains(_cancelToken.Value))
  159.                 break;
  160.             Add(item);
  161.         }
  162.         EndUpdate();
  163.     }
  164.  
  165.     public void AddRange(List<T> list)
  166.     {
  167.         if (_isDispose)
  168.             return;
  169.         if (_cancelTokensDict != null && _cancelToken.HasValue && _cancelTokensDict.Contains(_cancelToken.Value))
  170.             return;
  171.         if (list == null)
  172.             throw new ArgumentNullException("list");
  173.  
  174.         BeginUpdate();
  175.         for (int i = 0; i < list.Count; i++)
  176.         {
  177.             if (_cancelTokensDict != null && _cancelToken.HasValue && _cancelTokensDict.Contains(_cancelToken.Value))
  178.                 break;
  179.             var item = list[i];
  180.             if (_cancelTokensDict != null && _cancelToken.HasValue && _cancelTokensDict.Contains(_cancelToken.Value))
  181.                 break;
  182.             Add(item);
  183.         }
  184.         EndUpdate();
  185.     }
  186.  
  187.     #endregion Add 
  188.  
  189.     #region Remove
  190.  
  191.     public bool Remove(T item)
  192.     {
  193.         if (_isDispose)
  194.             return false;
  195.         if (_cancelTokensDict != null && _cancelToken.HasValue && _cancelTokensDict.Contains(_cancelToken.Value))
  196.             return false;
  197.         int index = _items.IndexOf(item);
  198.         if (index < 0) return false;
  199.         RemoveItem(item, index);
  200.         return true;
  201.     }
  202.  
  203.     private void RemoveItem(T removedItem, int index)
  204.     {
  205.         _items.RemoveAt(index);
  206.         OnPropertyChanged(COUNT);
  207.         OnPropertyChanged(ITEMS);
  208.         OnCollectionChanged(NotifyCollectionChangedAction.Remove, removedItem, index);
  209.     }
  210.  
  211.     #endregion Remove
  212.  
  213.     #region Clear
  214.  
  215.     public void Clear()
  216.     {
  217.         if (_isDispose)
  218.             return;
  219.         if (_cancelTokensDict != null && _cancelToken.HasValue && _cancelTokensDict.Contains(_cancelToken.Value))
  220.             return;
  221.         _items.Clear();
  222.         OnPropertyChanged(COUNT);
  223.         OnPropertyChanged(ITEMS);
  224.         OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
  225.     }
  226.  
  227.     #endregion Clear
  228.  
  229.     #region GetEnumerator
  230.  
  231.     public IEnumerator<T> GetEnumerator()
  232.     {
  233.         return _items.GetEnumerator();
  234.     }
  235.  
  236.     IEnumerator IEnumerable.GetEnumerator()
  237.     {
  238.         return ((IEnumerable)_items).GetEnumerator();
  239.     }
  240.  
  241.     #endregion GetEnumerator
  242.  
  243.     #region Dispose
  244.  
  245.     bool _isDispose = false;
  246.     public void Dispose()
  247.     {
  248.         if (!_isDispose)
  249.         {
  250.             _isDispose = true;
  251.             if (_cancelToken != null && _cancelTokensDict != null)
  252.             {
  253.                 _cancelTokensDict.Add(_cancelToken.Value);
  254.             }
  255.             if (_items != null)
  256.             {
  257.                 _items.Clear();
  258.             }
  259.             while (_losts.TryDequeue(out NotifyCollectionChangedEventArgs item))
  260.             { // do nothing
  261.             }
  262.         }
  263.     }
  264.  
  265.     #endregion Dispose
  266.  
  267.     public void BeginUpdate()
  268.     {
  269.         if (_isDispose)
  270.             return;
  271.         _isInAddRange = true;
  272.     }
  273.  
  274.     public void EndUpdate()
  275.     {
  276.         if (_isDispose)
  277.             return;
  278.         _isInAddRange = false;
  279.         OnPropertyChanged(COUNT);
  280.         OnPropertyChanged(ITEMS);
  281.         OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
  282.     }
  283.  
  284.     public void UpdateTotalItems(int count)
  285.     {
  286.         if (_updateTotalItems != null)
  287.         {
  288.             _updateTotalItems.UpdateTotalItems(count);
  289.         }
  290.     }
  291.  
  292.     public void Enqueue(NotifyCollectionChangedEventArgs e)
  293.     {
  294.         bool sendToHandle = false;
  295.         lock (_locker)
  296.         {
  297.             if (!_isLoading)
  298.             {
  299.                 sendToHandle = true;
  300.             }
  301.         }
  302.         if (sendToHandle)
  303.         {
  304.             Handle(e);
  305.         }
  306.         else
  307.         {
  308.             lock (_losts)
  309.             {
  310.                 _losts.Enqueue(e);
  311.             }
  312.         }
  313.     }
  314.  
  315.     public void PopulateFromLost()
  316.     {
  317.         if (_isDispose)
  318.             return;
  319.         if (_cancelTokensDict != null && _cancelToken.HasValue && _cancelTokensDict.Contains(_cancelToken.Value))
  320.             return;
  321.  
  322.         lock (_losts)
  323.         {
  324.             while (_losts.TryDequeue(out NotifyCollectionChangedEventArgs e))
  325.             {
  326.                 if (_cancelTokensDict != null && _cancelToken.HasValue && _cancelTokensDict.Contains(_cancelToken.Value))
  327.                     break;
  328.                 Handle(e);
  329.             }
  330.         }
  331.     }
  332.  
  333.     private void Handle(NotifyCollectionChangedEventArgs e)
  334.     {
  335.         if (_cancelTokensDict != null && _cancelToken.HasValue && _cancelTokensDict.Contains(_cancelToken.Value))
  336.             return;
  337.         switch (e.Action)
  338.         {
  339.             case NotifyCollectionChangedAction.Add:
  340.                 {
  341.                     foreach (var item in e.NewItems)
  342.                     {
  343.                         try
  344.                         {
  345.                             if (_cancelTokensDict != null && _cancelToken.HasValue && _cancelTokensDict.Contains(_cancelToken.Value))
  346.                                 break;
  347.  
  348.                             _items.Insert(e.NewStartingIndex, (T)item);
  349.                         }
  350.                         catch (Exception ex)
  351.                         {
  352.                             Trace.WriteLine($"Handle:Add, e.NewStartingIndex:{e.NewStartingIndex}, Error:{ex.Message}");
  353.                         }
  354.                     }
  355.                 }
  356.                 break;
  357.             case NotifyCollectionChangedAction.Remove:
  358.                 {
  359.                     foreach (var item in e.OldItems)
  360.                     {
  361.                         try
  362.                         {
  363.                             if (_cancelTokensDict != null && _cancelToken.HasValue && _cancelTokensDict.Contains(_cancelToken.Value))
  364.                                 break;
  365.  
  366.                             _items.Remove((T)item);
  367.                         }
  368.                         catch (Exception ex)
  369.                         {
  370.                             Trace.WriteLine($"Handle:Remove, Error:{ex.Message}");
  371.                         }
  372.                     }
  373.                 }
  374.                 break;
  375.             case NotifyCollectionChangedAction.Move:
  376.                 {
  377.                     try
  378.                     {
  379.                         if (_cancelTokensDict != null && _cancelToken.HasValue && _cancelTokensDict.Contains(_cancelToken.Value))
  380.                             break;
  381.  
  382.                         var itemMoved = (T)e.OldItems[0];
  383.                         _items.Remove(itemMoved);
  384.                         _items.Insert(e.NewStartingIndex, itemMoved);
  385.                     }
  386.                     catch (Exception ex)
  387.                     {
  388.                         Trace.WriteLine($"Handle:Move, e.OldStartingIndex:{e.OldStartingIndex}, e.NewStartingIndex:{e.NewStartingIndex}, Error:{ex.Message}");
  389.                     }
  390.                 }
  391.                 break;
  392.         }
  393.     }
  394. }
Sep 1 '22 #1
0 6704

Sign in to post your reply or Sign up for a free account.

Similar topics

0
by: chan | last post by:
how to apply online update function into program (the effect just like Norton system work live update) The situation is below: I want to develop a program that contains some product...
1
by: serge calderara | last post by:
Dear all, What is the way to implement a kind of link to a web site in order to inform my user that new updates are available to download, or even start the download automatically inside a VB...
17
by: kalamos | last post by:
This statement fails update ded_temp a set a.balance = (select sum(b.ln_amt) from ded_temp b where a.cust_no = b.cust_no and a.ded_type_cd = b.ded_type_cd and a.chk_no = b.chk_no group by...
3
by: pkumar | last post by:
How to implement live update, like stock ticker updates shown in TV .
3
by: Asim Qazi | last post by:
Hi all, I am trying to do some work like the All antivirus software do. -i-e LIVE UPDATE. for my software, wot is the starting point or any guidelines to start this thing ... I always did the...
2
by: Jassim Rahma | last post by:
how can i make a live update feature for my application?
1
by: kathnicole | last post by:
Hi All, I am asked to build a database for a Printing Company that would prepare a Job quote for the Customers and review the stocks available to carry out the Job. Stock Information performs...
2
by: vikastyagi | last post by:
i need norton 2007 updater patch pls send me link of any website for norton 2007 & sp2 any one solved me prob
1
Sl1ver
by: Sl1ver | last post by:
Hi guyz I have been surfing the web for a while know and im not exactly too sure what to search for as i dont have much jquery, ajax experiance. I need help, finger in the right direction or a...
5
by: sarah aziz | last post by:
Hello guys, i found this great post http://www.99points.info/2010/07/facebook-style-wallpost-and-comments-system-using-jquery-ajax-and-php-reloaded/ It is about post and comments like on facebook,...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.