473,230 Members | 1,720 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,230 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 6575

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: VivesProcSPL | last post by:
Obviously, one of the original purposes of SQL is to make data query processing easy. The language uses many English-like terms and syntax in an effort to make it easy to learn, particularly for...
0
by: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
0
by: stefan129 | last post by:
Hey forum members, I'm exploring options for SSL certificates for multiple domains. Has anyone had experience with multi-domain SSL certificates? Any recommendations on reliable providers or specific...
0
Git
by: egorbl4 | last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: Aftab Ahmad | last post by:
Hello Experts! I have written a code in MS Access for a cmd called "WhatsApp Message" to open WhatsApp using that very code but the problem is that it gives a popup message everytime I clicked on...

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.