Related to #457.
Sometimes it's necessary to manipulate the UI thread from the background thread. The task snippets repository, contains two snippets that should be inside the DispatcherHelper:
Like this ones.
I'm sure we can do an even simpler version for 2.
Hmm, interesting. I have always found myself doing this pretty regularly with the longer syntax. I'll see what I can do. PR soon.
The downside of the first snippet is that it always runs on the MainWindow thread. So it will work for single window apps, but as soon as you open up a secondary window, you will need to change all your code to invoke the right dispatcher. So I am not 100% sure this would be such a good thing to add. At least, if added, it should be named appropriately, e.g. DispatchOnMainWindowAsync(), to make things clear.
Agree
I will keep this in mind. Wrote bunch of buggy code last weekend, need more work before it is ready for PR.
Sorry for a long delay, been pretty busy with work. But I have a suggestion here for the probelm that @lukasf notified about:
Windows.ApplicationModel.Core.CoreApplication.GetCurrentView()?.CoreWindow?.Dispatcher?.RunAsync(CoreDispatcherPriority.Normal, handler);
This will guarantee that the current window thread will be the one to execute the code. This comes with 1 disadvantage: CoreApplication.GetCurrentView() could return null if no view has been activated (as expected). MainView is always guaranteed to be there.
Should we have an overload for this (as one will always execute on the Main Window Thread and the overload to have an option to choose for the currently active one instead)?
@Code-ScottLe Well, if we are on the UI thread already, there is no need to call CallOnUIThreadAsync(), right? You could just call your method directly then... ;-)
@lukasf Well, it can still happen in my previous experiences. I.E: you run something with Task.Run(), which will execute on a different thread, and then somehow ending up updating the UI (most common scenario, is through events handler delegate).
I think GetCurrentView is just for the currently activate view/window (got focus?). I have never done an UWP that has 2 or more windows and I don't think they are that common either, but still :P
@Code-ScottLe In UWP, each Window has its own UI thread. The GetForCurrentView() method will return the ApplicationView for the Window that is running on the current thread. So if you call this function on the MainWindow's UI thread, you will get the MainWindow ApplicationView, if you call it from a secondary Window's UI thread, you will get the secondary ApplicationView. But if you call it on a background thread, you will get an exception, no matter if you have a Window active or not. The MSDN docs on the method are not very clear about this, but that's how it works. That's why this method won't help you here. You want to call from a background thread, but the method only works on the UI thread.
@lukasf So it sounds like GetForCurrentView() will just return the view that the caller thread is associated with (hence the exception thrown if called from background thread)?
MSDN has only a single line description on this...
Correct, and I also think that the docs could be clearer here. There are also other classes with a GetForCurrentView() method, they all work like this.
Most helpful comment
Hmm, interesting. I have always found myself doing this pretty regularly with the longer syntax. I'll see what I can do. PR soon.