I'm working wih an ObservableCollection
in MultiThreading environment. Since ObservableCollection
is not thread-safe I have to do my own syncronization using locks.
So, When I have to read, write, or remove elements from the ObservableCollection
I use lock
Also, since it is binding to UI, every updates to UI have to be done on MainThread. In WPF it seems that if you use BindingOperations.EnableCollectionSyncronization
everythings is working well without explicitly calling MainThread, in Xamarin (Android) it seems that it doesn't work.
I would like to clarify if using EnableCollectionSyncronization needs also to use lock(as MS doc sais I think so), but I don't understand the different behaviours in WPF and Xamarin.
WPF
public class ExampleWPF{
public Example(){
var _lock = new Object();
var _observableCollection = new ObservableCollection<string>();
BindingOperations.EnableCollectionSyncronization(_observableCollection, _lock);
}
public void Add(){
lock(_lock){
_observableCollection.Add("Example");
}
}
public void Search(){
lock(_lock){
_observableCollection.FirstOrDefault(x => x == "Example");
}
}
}
Xamarin
I have try also to quit explicit calling to MainThread on methods and calling it on ObservableCollectionCallback()
but it seems that it doesn't work, the UI gets freezed but no exception is thrown.
public class ExampleXamarin{
public Example(){
var _lock = new Object();
var _observableCollection = new ObservableCollection<string>();
BindingBase.EnableCollectionSyncronization(_observableCollection, _lock, ObservableCollectionCallback);
}
private void ObservableCollectionCallback(ICollection collection, Object context, Action accessMethod, bool writeAccess){
lock(context){
accessMethod?.Invoke();
}
}
public void Add(){
lock(_lock){
Device.BeginInvokeOnMainThread(() =>_observableCollection.Add("Example"));
}
}
public void Remove(){
lock(_lock){
var iten = _observableCollection.FirstOrDefault(x => x == "Example");
Device.BeginInvokeOnMainThread(() =>_observableCollection.Remove(item));
}
}
public void Search(){
lock(_lock){
_observableCollection.FirstOrDefault(x => x == "Example");
}
}
}