我正在尝试通过Dispatcher从后台线程更新一些UWP UI。 但是,传递给RunAsync方法的处理程序仍在backlground线程上执行。
我不知道该如何解决-我错过了什么吗?
-编辑-
我只有一个窗口,即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 ?? "");
});
}
答案 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)
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在我确定这是调度问题时试图帮助我。