UWP-调度程序DispatchedHandler如何在辅助线程上运行?

时间:2018-09-17 17:40:06

标签: xaml uwp

我正在尝试通过Dispatcher从后台线程更新一些UWP UI。 但是,传递给RunAsync方法的处理程序仍在backlground线程上执行。

我不知道该如何解决-我错过了什么吗?

enter image description here

-编辑-

我只有一个窗口,即Window.Current

我已经尝试了Community Toolkit DispatcherHelper类,但仍然遇到完全相同的异常

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 ?? "");
    });

}

3 个答案:

答案 0 :(得分:2)

如果您已经在后台线程上,则无法访问Window.Current.Dispatcher,因为后台线程未设置Window.Current(该属性获取与UI线程关联的Window实例呼叫)。

相反,您应该首先在UI线程上检索Dispatcher实例,然后使用该实例执行RunAsync

但是-OnSelectedItemChanged似乎是一个UI事件处理程序,在这种情况下,您不需要在UI线程上运行代码。例如,如果您是通过UnauthorizedAccessException点击触发的,只是使用相同的参数运行panel.DescriptionBox.Document.SetText,请检查Button是否不会发生。

多视图和多窗口应用程序

如果您正在创建多视图或多窗口UWP应用,则可能会出现问题,因为在UWP中,每个窗口都有其自己的UI线程。这意味着,当您想要跨窗口更新属性时,始终需要使用目标窗口/应用程序视图的Dispatcher

答案 1 :(得分:1)

WindowsCommunityToolkit 中的

DispatcherHelper在这里可能会很有帮助。

它使您可以选择在UI线程上执行代码或在MainView上执行代码(如果您有多个窗口)

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

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

});

答案 2 :(得分:1)

好的,我终于发现发生了什么事,这不是我所期望的。

该问题与线程或调度程序无关,尽管调度程序在工作线程上执行(UWP调度程序似乎并不像WPF那样在主线程上运行),尽管该错误与您将要发生的错误相同期望您是否有跨线程UI异常。

原来,我有一个RichEditBox,它在无意中处于只读模式。并且由于该控件不支持绑定到其内容,因此我在代码隐藏中设置了内容。例外是因为我在控件处于只读模式时设置了文本。

很遗憾,该控件无法给出更有意义的错误,或者即使在只读模式下也无法以编程方式进行编辑-例如WPF等效项。但是,你去了。希望这个“问答”页面可以帮助遇到相同问题的其他人。

非常感谢Martin Zikmund在我确定这是调度问题时试图帮助我。