UWP - Как Dispatcher DispatchedHandler может работать в рабочем потоке? - PullRequest
0 голосов
/ 17 сентября 2018

Я пытаюсь обновить пользовательский интерфейс UWP из фонового потока через диспетчер.Однако обработчик, переданный методу RunAsync, все еще выполняется в фоновом потоке.

Понятия не имею, как это исправить - я что-то пропустил?

enter image description here

- РЕДАКТИРОВАТЬ -

У меня есть только одно окно, которое Window.Current

Я пробовал Набор инструментов сообщества 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 голосов
/ 17 сентября 2018

DispatcherHelper из WindowsCommunityToolkit может быть очень полезным здесь.

это дает вам возможность выполнить код в потоке пользовательского интерфейса или выполнить код в MainView (если у вас естьнесколько окон)

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

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

});
0 голосов
/ 20 сентября 2018

ОК, я наконец выяснил, что происходит, и это было не то, что я ожидал.

Проблема не имела ничего общего с потоками или диспетчерами, несмотря на то, что диспетчер выполнялся в рабочем потоке (Диспетчеры UWP, похоже, не работают в главном потоке, как WPF, кажется), и, несмотря на то, что ошибка является той же самой ошибкой, которую вы ожидаете, если у вас возникла исключительная ситуация с многопоточным пользовательским интерфейсом.

Оказывается, я имелRichEditBox, который был случайно в режиме только для чтения.И поскольку этот элемент управления не поддерживает привязку к его содержимому, я устанавливал содержимое в коде позади.Исключением было то, что я устанавливал текст элемента управления, когда он находился в режиме только для чтения.

Жаль, что элемент управления не мог выдать более значимую ошибку или быть редактируемым программно, даже если врежим только для чтения - как эквивалент WPF.Но вот, пожалуйста.Надеюсь, что эта страница вопросов и ответов поможет кому-то еще с такими же проблемами.

Большое спасибо Мартину Зикмунду за попытку помочь мне, когда я был уверен, что это была проблема с отправкой.

0 голосов
/ 17 сентября 2018

Если вы уже находитесь в фоновом потоке, вы не можете получить доступ к Window.Current.Dispatcher, поскольку фоновый поток не имеет установленного Window.Current (свойство получает экземпляр Window, связанный с потоком пользовательского интерфейса, из которого он вызывается).

Вместо этого вы должны сначала извлечь экземпляр Dispatcher в потоке пользовательского интерфейса, а затем использовать этот экземпляр для выполнения RunAsync.

Однако - OnSelectedItemChanged скорее выглядит как обработчик события пользовательского интерфейса, в которомВ этом случае вам не нужно запускать код в потоке интерфейсаПроверьте, не произойдет ли UnauthorizedAccessException, если вы просто запустите panel.DescriptionBox.Document.SetText с теми же параметрами при запуске, например, при нажатии Button.

Приложения с несколькими окнами просмотра и с несколькими окнами

Проблема может возникнуть в случае, если вы создаете приложение UWP с несколькими окнами или несколькими окнами, поскольку в UWP каждое окно имеет свой собственный поток пользовательского интерфейса.Это означает, что когда вы хотите обновить свойства в разных окнах, вам всегда нужно использовать Dispatcher целевого окна / представления приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...