UWP - How Can Dispatcher DispatchedHandler Run On Worker Thread?

你。 提交于 2021-02-11 14:17:03

问题


Im trying to update some UWP UI from a background thread via the Dispatcher. However, the handler passwed to the RunAsync method is still getting executed on a backlground thread.

I have no idea how to fix this - have I missed something?

--EDIT--

I only have one window, which is Window.Current

I have tried the Community Toolkit DispatcherHelper class, but I'm still getting the exact same exception

private static async void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var panel = (SidePanelInfo) d;
    var x = e.NewValue as TaskItemViewModel;
    await DispatcherHelper.ExecuteOnUIThreadAsync(() =>
    {
        panel.DescriptionBox.Document.SetText(TextSetOptions.FormatRtf, x?.Description ?? "");
    });

}

回答1:


If you are already on the background thread, you cannot access Window.Current.Dispatcher as the background thread has no Window.Current set (the property gets the Window instance associated with the UI thread it is called from).

Instead you should first retrieve the Dispatcher instance while on the UI thread and then use this instance to execute RunAsync.

However - OnSelectedItemChanged rather seems like a UI event handler in which case you should not require running code on UI thread. Check if the UnauthorizedAccessException does not happen if you just run panel.DescriptionBox.Document.SetText with the same parameters when triggered from a Button click for example.

Multi-view and multi-window apps

The problem can occur in case you are creating a multi-view or multi-window UWP app, because in UWP each window has its own UI thread. This means that when you want to update properties across windows, you always need to use the Dispatcher of the target window/app view.




回答2:


DispatcherHelper from the WindowsCommunityToolkit can be very helpful here.

it gives you option to execute code on UI thread or execute code on MainView ( if you have multiple windows )

DispatcherHelper.ExecuteOnUIThreadAsync<T>(() =>
{
    // Code to execute on main window's UI thread
});

await CoreApplication.MainView.Dispatcher.AwaitableRunAsync<T>( () =>
{

});



回答3:


OK, I have finally found out what was going on, and it was not what I was expecting.

The issue had nothing to do with threading or dispatchers, despite the dispatcher executing on a worker thread (UWP dispatchers dont seem to run on the Main Thread like WPF it seems), and despite the error being the same error as you would expect if you had a cross-threading UI exception.

It turns out that I had a RichEditBox that was inadvertently in read-only mode. And because this control doesn't support binding to its content, I was setting the content in code-behind. The exception was because I was setting the text of the control while it was in read-only mode.

It's a shame that the control couldn't have given a more meaningful error, or been editable programmatically even if in read-only mode - like the WPF equivalent. But there you go. Hopfully this Q&A page will help someone else having the same problems.

A big thanks to Martin Zikmund for attempting to help me when I was sure it was a dispatching issue.



来源:https://stackoverflow.com/questions/52373127/uwp-how-can-dispatcher-dispatchedhandler-run-on-worker-thread

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!