public void CollectionAndContextAreHeldWeaklyClosingOverCollection() { WeakReference weakCollection = null, weakContext = null; int i = 0; Action create = null; create = () => { if (i++ < 1024) { create(); return; } string[] collection = new[] { "foo", "bar" }; weakCollection = new WeakReference(collection); object context = new object(); weakContext = new WeakReference(context); BindingBase.EnableCollectionSynchronization(collection, context, (enumerable, o, method, access) => { collection[0] = "baz"; }); }; create(); GC.Collect(); GC.WaitForPendingFinalizers(); Assert.IsFalse(weakCollection.IsAlive); Assert.IsFalse(weakContext.IsAlive); }
public void SynchronizedCollectionAccess() { var collection = new ObservableCollection <string> { "foo" }; var context = new object(); var list = new ListProxy(collection); bool executed = false; BindingBase.EnableCollectionSynchronization(collection, context, (enumerable, o, method, access) => { executed = true; Assert.AreSame(collection, enumerable); Assert.AreSame(context, o); Assert.IsNotNull(method); Assert.IsFalse(access); lock (enumerable) method(); }); object value = list[0]; Assert.IsTrue(executed, "Callback was not executed"); }
public ContactsViewModel(INavigation navigation) : base(navigation) { Contacts = new ObservableCollection <ContactModel>(); BindingBase.EnableCollectionSynchronization(Contacts, null, ObservableCollectionCallback); App.ContactsService.OnContactLoaded += OnContactLoaded; LoadContacts(); }
public LogViewerModel() { Logs = new ObservableCollection <LogMsg>(); Log.LogsSink.OnLogEmit = new AsyncCommand <LogMsg>(OnLogEmit); MaxLogs = 500; BindingBase.EnableCollectionSynchronization(Logs, _syncLock, ObservableCollectionCallback); }
public CollectionViewModel() { Title = "Browse"; Items = new RangeObservableCollection <T>(); BindingBase.EnableCollectionSynchronization(Items, null, ObservableCollectionCallback); LoadItemsCommand = new Command(async() => await ExecuteLoadItemsCommand()); AddItemCommand = new AsyncCommand <T>(async(item) => await ExecuteAddItemCommand(item)); }
public void EnableCollectionSynchronizationInvalid() { Assert.That(() => BindingBase.EnableCollectionSynchronization(null, new object(), (collection, context, method, access) => { }), Throws.InstanceOf <ArgumentNullException>()); Assert.That(() => BindingBase.EnableCollectionSynchronization(new string[0], new object(), null), Throws.InstanceOf <ArgumentNullException>()); Assert.That(() => BindingBase.EnableCollectionSynchronization(new string[0], null, (collection, context, method, access) => { }), Throws.Nothing); }
public Task SynchronizedCollectionAdd() => DispatcherTest.Run(() => { bool invoked = false; DispatcherProviderStubOptions.IsInvokeRequired = () => true; DispatcherProviderStubOptions.InvokeOnMainThread = action => { invoked = true; action(); }; var collection = new ObservableCollection <string> { "foo" }; var context = new object(); var list = new ListProxy(collection); Assert.IsFalse(invoked, "An invoke shouldn't be executed just setting up ListProxy"); bool executed = false; BindingBase.EnableCollectionSynchronization(collection, context, (enumerable, o, method, access) => { executed = true; Assert.AreSame(collection, enumerable); Assert.AreSame(context, o); Assert.IsNotNull(method); Assert.IsFalse(access); lock (enumerable) method(); }); var mre = new ManualResetEvent(false); Task.Factory.StartNew(() => { DispatcherProviderStubOptions.IsInvokeRequired = () => true; DispatcherProviderStubOptions.InvokeOnMainThread = action => { invoked = true; action(); }; lock (collection) collection.Add("foo"); mre.Set(); }, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default); mre.WaitOne(5000); Assert.IsTrue(executed, "Callback was not executed"); Assert.IsTrue(invoked, "Callback was not executed on the UI thread"); });
public void DisableCollectionSynchronization() { string[] stuff = new[] { "foo", "bar" }; object context = new object(); CollectionSynchronizationCallback callback = (collection, o, method, access) => { }; BindingBase.EnableCollectionSynchronization(stuff, context, callback); BindingBase.DisableCollectionSynchronization(stuff); CollectionSynchronizationContext syncContext; Assert.IsFalse(BindingBase.TryGetSynchronizedCollection(stuff, out syncContext)); Assert.IsNull(syncContext); }
public void EnableCollectionSynchronization() { string[] stuff = new[] { "foo", "bar" }; object context = new object(); CollectionSynchronizationCallback callback = (collection, o, method, access) => { }; BindingBase.EnableCollectionSynchronization(stuff, context, callback); CollectionSynchronizationContext syncContext; Assert.IsTrue(BindingBase.TryGetSynchronizedCollection(stuff, out syncContext)); Assert.That(syncContext, Is.Not.Null); Assert.AreSame(syncContext.Callback, callback); Assert.That(syncContext.ContextReference, Is.Not.Null); Assert.That(syncContext.ContextReference.Target, Is.SameAs(context)); }
public NewsViewModel() { //Ensure Observable Collection is thread-safe https://codetraveler.io/2019/09/11/using-observablecollection-in-a-multi-threaded-xamarin-forms-application/ BindingBase.EnableCollectionSynchronization(TopStoryCollection, null, ObservableCollectionCallback); }
public OpportunitiesViewModel() { //https://codetraveler.io/2019/09/11/using-observablecollection-in-a-multi-threaded-xamarin-forms-application/ BindingBase.EnableCollectionSynchronization(VisibleOpportunitiesCollection, null, ObservableCollectionCallback); }
public PhotoListViewModel() { //https://codetraveler.io/2019/09/11/using-observablecollection-in-a-multi-threaded-xamarin-forms-application/ BindingBase.EnableCollectionSynchronization(AllPhotosList, null, ObservableCollectionCallback); }
public OpportunitiesViewModel() { BindingBase.EnableCollectionSynchronization(VisibleOpportunitiesCollection, null, ObservableCollectionCallback); }
public FileBrowserDirectoryAdapter(params IFileSystemDiscovery[] fileSystemDiscoverers) { _fileSystemDiscoverers = fileSystemDiscoverers; BindingBase.EnableCollectionSynchronization(_items, null, ObservableCollectionCallback); NavigateToFileSystemItemAsync(CreateRootItem(_fileSystemDiscoverers)); }