Click here to Skip to main content
Licence LGPL3
First Posted 13 Dec 2010
Views 3,454
Downloads 0
Bookmarked 0 times

Async BackgroundTaskManager and ObservableCollection

By | 14 Dec 2010 | Technical Blog
Async BackgroundTaskManager and ObservableCollection
A Technical Blog article. View original blog here.[^]

AsyncBackgroundTaskManager and AsyncObservableCollection is a BackgroundTaskManager/ObservableCollection that supports a list and runs asynchronously.

Introduction

Cinch included a class named BackgroundTaskManager, which offloads CPU hogging work from UI thread, and notifies the UI when a work is completed.

BackgroundTaskManager uses BackgroundWorker to do the tricks, but it is easier to use:

BackgroundTaskManager<string> _bgWorker = new BackgroundTaskManager<string>(
  () => { return CPUHoggingWork(); }
  (result) => { Result = result; }
);

The advantage of using BackgroundTaskManager is that you can write all related code in one place, and you won’t mis-write UI updating code in non-UI thread (and vice versa).

BackgroundTaskManager worked for me in most cases except when I wanted to use it to return a list of items, BackgroundTaskManager only allows return all items when the computation is completed, but I wanted it to return an item as soon as it’s constructed. So the result is AsyncBackgroundTaskManager, a BackgroundTaskManager that supports async tasks.

Although ObservableCollection has a constructor that takes IEnumerable<T>, it still blocks the thread when it’s loading, so after I completed the AsyncBackgroundTaskManager, I derived a new ObservableCollection class, named AsyncObservableCollection, which uses AsyncBackgroundTaskManager to populate its items in a separated thread.

How to Use?

The constructor of AsyncBackgroundTaskManager takes a couple parameters:

  • taskFunc (Func<IEnumerable<T>>) or taskEnumerable (IEnumerable<T>) - Specify what to return here, you can use linq or a method that returns IEnumerable<T>.
  • newItemAction (Action<T>) – Runs in UI Thread when a new item is prepared.
  • removeItemAction (Action<T>) – Optional, Runs in UI Thread when an item should be removed.
  • completeAction (Action<IList<T>>) – Runs in UI Thread when taskFunc is completed.
_bgWorker2 = new AsyncBackgroundTaskManager<StringModel>(DispatcherPriority.SystemIdle,
    from fi in new DirectoryInfo(_path).EnumerateFiles("*", SearchOption.AllDirectories)
        select new StringModel(fi.FullName),
    (model) => { InternalCollection.Add(model); },
    (model) => { InternalCollection.Remove(model); },
    (modelList) => { _aborted = (modelList == null); });
_bgWorker2.RunBackgroundTask();

The constructor of AsyncObservableCollection takes similar parameters, taskFunc and completeAction:

_internalCollection2 = new AsyncObservableCollection<StringModel>(
    from fi in new DirectoryInfo(_path).EnumerateFiles("*", SearchOption.AllDirectories)
    select new StringModel(fi.FullName),
    (modelList) => { Debug.WriteLine(modelList.Count.ToString() + " polled."); }
);
_internalCollection2.Load(false);

How It Works?

There are only 158 lines in the AsyncBackgroundTaskManager class, so you won't find any magic there.

The code below appears many times. It alerts the UI thread when the collection should be changed.

 _dispatcher.Invoke(_priority, new ThreadStart(() =>
            {
                //Do something
            }));

So compared with BackgroundTaskManager, instead of using BackgroundWorker, it creates a new Thread to invoke TaskFunc, then loop the IEnumerator for items. Then for each item returned, it alerts the UI Thread using NewItemAction.

Further Improvements

Performance is affected because it invokes the UI thread every time when a new item is returned, this can be avoided if I change the component so instead of pushing new item to UI thread, the UI thread creates a DispatcherTimer to pull new items when it has time.

Reference

This article has been posted on . You can find a list of my articles here.


License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)

About the Author

Leung Yat Chun

Software Developer

Hong Kong Hong Kong

Member

DirectoryInfoEx - 0.22
 
WPF FileExplorer - 0.8
 
WPF ListView MultiSelect - 0.4
 
WPF Aero Titlebar - 0.2

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
NewsVersion 2 PinmemberLeung Yat Chun22:17 23 Dec '10  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web03 | 2.5.120517.1 | Last Updated 14 Dec 2010
Article Copyright 2010 by Leung Yat Chun
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid