-1

I have followed this blog by Stephen Cleary and I was wondering what would be the best approach for update the existing collection that is bounded to the UI which updates every 15 seconds? For e.g. do I Clear the list then add a new collection to create a new object?

I am asking this question because when I added this Task taskA = Task.Run(() => UpdateManifest(_ManifestToken.Token)); line of code my CPU increase rapidly.

C#:

// Ctor.
public ManifestViewModel()
{
    _ManifestItems = new NotifyTaskCompletion<ObservableCollection<ManifestItem>>(FetchData());
    Task taskA = Task.Run(() => UpdateManifest(_ManifestToken.Token));  
}

private NotifyTaskCompletion<ObservableCollection<ManifestItem>> _ManifestItems;
public NotifyTaskCompletion<ObservableCollection<ManifestItem>> ManifestItems
{
    get => _ManifestItems;
    set
    {
        if (_ManifestItems != value)
        {
            _ManifestItems = value;
            OnPropertyChanged();
        }
    } 
 }

public static Task UpdateManifest(CancellationToken token)
{
    while (true)
    {
        _ManifestItems = new NotifyTaskCompletion<ObservableCollection<ManifestItem>>(FetchData());

        Task.Delay(15000);
    }
}
Dev
  • 1,780
  • 3
  • 18
  • 46
  • "most counter-intuitive" ?? you want the most difficult and hardest to understand method? – MikeT May 16 '18 at 09:51

1 Answers1

1

You should fetch the data on a background thread and update the source collection on the UI thread. You could also use the BindingOperations.EnableCollectionSynchronization method enable the data-bound collection to be updated from a background thread.

A better way than calling Updatemanifest from your constructor and use a while (true) loop would be to use a Timer that fetches the data at given intervals, e.g.:

private void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    var data = FetchData();

    //either just set a source property to the fetched data collection
    SourceCollectionProperty = data;

    //...or update the collection

}
mm8
  • 163,881
  • 10
  • 57
  • 88
  • So it is ok to do work on the background thread then sync back to the UI thread? Because I have read online that everything should be done on the UI thread(I never fully understand what this means)? or did I misunderstood or are there exceptions? [I read here](https://msdn.microsoft.com/en-us/magazine/dn605875.aspx) "Any direct use of Dispatcher... ...is a bad idea." – Dev May 16 '18 at 10:14
  • In WPF, the `DispatchTimer` would probably be the most appropriate, since it eliminates the need to worry about the threads. As long as the job running in the timer isn't heavy enough to bog down the UI. – Bradley Uffner May 16 '18 at 10:24
  • @BradleyUffner Yes, It is WPF I often use the just synchronous code but when I tried my app on a slow internet it would freeze the UI so I am researching Asynchronous to get a more responsive UI. – Dev May 16 '18 at 10:32
  • [Here is an example](https://stackoverflow.com/questions/12442622/async-friendly-dispatchertimer-wrapper-subclass) is an `async` / `await` friendly `DispatchTimer` sub-class that looks like it would be perfect. – Bradley Uffner May 16 '18 at 10:34
  • It's not only "ok" to" do work on the background thread then sync back to the UI thread". It's how you are supposed to do things if you care about responsiveness. – mm8 May 16 '18 at 11:22
  • I don't see why I got downvoted would be great to get a feedback for future improvements. I have received three different suggestions is it a case that all of the three will give the same outcome. Yes, responsiveness is what I need more than anything. – Dev May 17 '18 at 11:15
  • So what is your current issue? – mm8 May 17 '18 at 13:07
  • No current Issue, it's just for "piece of mind" I have tried using `BindingOperations.EnableCollectionSynchronization` before and my app still locks up but it could be due to bad practices. Started from the ground up with what @mm8 posted and it works. My question was are all suggestions solution for responsiveness? for future reference as an alternative approach. – Dev May 17 '18 at 14:19