WPF: changing CollectionView from dispatcher still causes errors

I have the following bit of code that changes the observable collection of โ€œscreensโ€ whenever the user leaves.

void OnUserLeft(int roomId, int userId, string username) { client.ClientDispatcher.Invoke( (Action<int>)((id) => { Console.WriteLine("Hello before the storm!"); var screensToCheck = client.Screens.Where(s => s.CpuId == id).ToList(); screensToCheck.Each(s => client.Screens.Remove(s)); Console.WriteLine("Hello there!"); }), userId); } 

This is wrapped up in a challenge to the client dispatcher, supposedly to get past the threading problems associated with CollectionViews. However, I still get the following exception:

This type of CollectionView does not support changes to the SourceCollection from a stream other than the Dispatcher stream.

The dispatcher that you see above is installed in the MainViewModel WPF application (we use MVVM), for example:

 public Dispatcher ClientDispatcher { get { return Dispatcher.CurrentDispatcher; } } 
+4
source share
1 answer

From the documentation of CurrentDispatcher :

Gets the dispatcher for the current thread and creates a new dispatcher if it is not already associated with the stream.

It looks like you are accessing the CurrentDispatcher , and not your user interface thread, and calling your operation on it (i.e., Invoke has no effect, because there is no Dispatcher in the thread you are in; it is created in place, and the call goes to him).

You must store the Dispatcher.CurrentDispatcher value in the place where you create the Client instances (assuming you do this from the user interface thread), for example:

 class Client { Client() { this.OwningDispatcher = Dispatcher.CurrentDispatcher; } Dispatcher OwningDispatcher { get; private set; } } 

If your Client instances are not created in the UI thread, you need to somehow get the correct Dispatcher value for them.

+6
source

Source: https://habr.com/ru/post/1309708/


All Articles