1

In my program I add objects to an ObservableCollection from a background worker thread by utilizing the AddOnUI extension method used in this answer.

The extension method that I am using:

public static void AddOnUI<T>(this ICollection<T> collection, T item)
{
    Action<T> addMethod = collection.Add;
    Application.Current.Dispatcher.BeginInvoke( addMethod, item );
}

...

collection.AddOnUI(new B());

This solution works perfectly for collection objects that get added from a background worker thread. However, when manually adding a collection object just on the UI thread with no background thread involved, the collection does not populate in data, or in the View. Is there a way to query what thread is active when calling an add method from an ObservableCollection?

Maybe do something like this?:

if(calling from background thread)
    collection.AddOnUI(new B());
else //Manually adding from UI Thread
    collection.Add(new B());

Solution:

My solution ended up being a lot similar to my pseudo code, which I really liked.

if(System.Threading.Thread.CurrentThread.IsBackground)
    collection.AddOnUI(new B());
else //Manually adding from UI Thread
    collection.Add(new B());

Alternate Solution:

AddOnUI() (Change BeginInvoke to Invoke):

public static void AddOnUI<T>(this ICollection<T> collection, T item)
{
    Action<T> addMethod = collection.Add;
    Application.Current.Dispatcher.Invoke(addMethod, item);
}

collection.AddOnUI(new B());
Community
  • 1
  • 1
Eric after dark
  • 1,768
  • 4
  • 31
  • 79

2 Answers2

2

System.Threading.Thread.CurrentThread tells you what thread you're on, which can compare against the Dispatcher.Thread property.

David
  • 10,458
  • 1
  • 28
  • 40
1

Checking for thread is a hacky solution. You don't need it at all because framework internally make sure to dispatch the operation on correct thread.

Issue most likely is you are adding object asynchronously (BeginInvoke). Add the object synchronously (Invoke) and you will see the item added immediately to the collection.

Replace

Application.Current.Dispatcher.BeginInvoke(addMethod, item);

with

Application.Current.Dispatcher.Invoke(addMethod, item);
Rohit Vats
  • 79,502
  • 12
  • 161
  • 185
  • Technically @Aravol's solution works as well, but I chose to implement Rohit Vat's solution due to its simplicity and better abstraction. – Eric after dark Nov 14 '14 at 19:57