Доступ к объекту из другого потока с помощью Dispatcher - PullRequest
0 голосов
/ 08 июля 2019

У меня есть поток, который работает в фоновом режиме во время асинхронной загрузки. Цель потока - определить, остановлена ​​ли загрузка. Мой код в основном говорит "если мы не загрузили больше байтов за последние 10 секунд, предположим, что загрузка не удалась, и сделайте это" .

Когда я попытался обновить метку в моем окне WPF, говоря, что загрузка остановлена, мне сказали, что я не могу получить к ней доступ из нестатической ссылки. Поэтому я добавил MainWindow main = new MainWindow(), а затем добавил это в переменную, чтобы элемент WPF не был статичным. Но мне также нужно было использовать Dispatcher, потому что другой объект уже владел этим объектом. Итак, мой код выглядел так:

MainWindow main = new MainWindow();
main.Dispatcher.BeginInvoke(new Action(delegate() {
    main.mainTitle.Content = "Unable to connect to the internet";
}));

Это ничего не изменило, поэтому я изменил свой подход. Я изменил Dispatcher на это:

MainWindow main = new MainWindow();
Application.Current.Dispatcher.BeginInvoke(new Action(delegate() {
    main.mainTitle.Content = "Unable to connect to the internet";
}));

Однако, похоже, это ничего не делает, потому что в строке, которая изменяет содержимое элемента WPF, я получил ошибку 'Вызывающий поток не может получить доступ к этому объекту, потому что другой поток владеет им.'

Как я могу изменить содержимое этого объекта из другого потока, и почему Dispatcher не работает?

1 Ответ

0 голосов
/ 11 июля 2019

Как я вижу, вы пытаетесь получить некоторую строку в MainWindow.Дело в том, что WPF начинается с двух потоков. Пользовательский интерфейс и Визуализация потока .Поток рендеринга начинает рендеринг экрана WPF, а поток пользовательского интерфейса отвечает за входные данные, обрабатывает события ...

В вашем случае вам необходимо разрешение для доступа к потоку пользовательского интерфейса из другого потока.Вы создали сами в коде.Мой диспетчер выглядит так:

System.Windows.Application.Current.Dispatcher.Invoke(delegate
{
     //your code to access property / variable / methods etc
});

Другой способ: почему вы не используете шаблон, такой как MVVM, с привязкой?Если вы используете привязку, вы можете изменить привязанное свойство, и значение будет автоматически обновляться в пользовательском интерфейсе.Я не уверен, является ли диспетчер 1014 * способом доступа к элементам WPF напрямую из другого потока.

...