I have the following code:
class Customers : BindableObject
{
private ObservableCollection<string> _Products = new ObservableCollection<string>();
public ObservableCollection<string> Products
{
get
{
return _Products;
}
set
{
_Products = value;
RaisePropertyChanged("Products");
}
}
private string _Name = "John";
public string Name
{
get
{
return _Name;
}
set
{
_Name = value;
RaisePropertyChanged("Name");
}
}
public Customers()
{
Products.Add("George");
Products.Add("Henry");
}
public void LongRunningFunction()
{
Name = "Boo";
Thread.Sleep(5000);
Name = "Peter";
}
public void ThreadedLongRunningFunction()
{
Task t = new Task(new Action(LongRunningFunction));
t.Start();
}
public void LongRunningFunctionList()
{
Products.Add("Boo");
Thread.Sleep(5000);
Products.Add("Booya");
}
public void ThreadedLongRunningFunctionList()
{
Task t = new Task(new Action(LongRunningFunctionList));
t.Start();
}
}
BindableObject implements INotifyPropertyChanged.
I then have in my MainWindow.xaml.cs
public partial class MainWindow : Window
{
Model.Customers c = new Model.Customers();
public MainWindow()
{
InitializeComponent();
gridToBindTo.DataContext = c;
}
private void cmdRun_Click(object sender, RoutedEventArgs e)
{
c.LongRunningFunction();
}
private void cmdRunAsync_Click(object sender, RoutedEventArgs e)
{
c.ThreadedLongRunningFunction();
}
private void cmdRunListSync_Click(object sender, RoutedEventArgs e)
{
c.LongRunningFunctionList();
}
private void cmdRunListAsync_Click(object sender, RoutedEventArgs e)
{
c.ThreadedLongRunningFunctionList();
}
}
My MainWindow has a label bound to Name, and a list box bound to Products.
In the threaded version of both of the functions, I don’t understand why I am allowed to operate on a property ‘Name’ (string) that is bound to the UI in another thread, but I’m not allowed to do the same for a ObservableCollection.
Can someone explain why there is a difference here ?
Regards
ObservableCollection is not
thread safethat’s why it can’t be modified across different Dispatchers. But you can always override the ObservableCollection to make it thread safe. Look at the sample here – http://tomlev2.wordpress.com/2009/04/17/wpf-binding-to-an-asynchronous-collection/Bottom line is to raise the
collectionChangedandpropertyChangedon the UI dipatcher where collection was created.