Вызывающий поток не может получить доступ к этому объекту, поскольку он принадлежит другому потоку. 'ошибка в потоке wpf - PullRequest
0 голосов
/ 15 мая 2018

У меня есть Окно 1, в котором при нажатии кнопки я открываю Окно 2 в новой теме. Ниже мой код

 private void Button_Click_2(object sender, RoutedEventArgs e)
    {
        Thread thread = new Thread(() =>
        {
            Scanner w = new Scanner();
            w.Show();

            w.Closed += (sender2, e2) =>
            w.Dispatcher.InvokeShutdown();

            System.Windows.Threading.Dispatcher.Run();
        });

        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();
    }

Окно 2 имеет форму. Я получаю значения формы при нажатии кнопки

 private void EnterProduct(object sender, RoutedEventArgs e)
    {
        var data = ProductDetailsData;
        LoadCurrentBetween objMain = new LoadCurrentBetween(); //new MainWindow();
        objMain.fillorderform(data);
    }

при нажатии кнопки в окне 2 я передаю значения формы другому View

public void fillorderform(dynamic data)
    {
        this.Dispatcher.Invoke(() =>
        {
            LoadCurrentdetails.Part = data.Part;
            LoadCurrentBetween loadCurrentbtw = new LoadCurrentBetween();
            Switcher.Switch(loadCurrentbtw);
        });          
    }  public static class Switcher
{
    public static MainWindow pageSwitcher;

    public static void Switch(UserControl newPage)
    {
        pageSwitcher.Navigate(newPage);
    }
}

Следующий код выдает ошибку в "this.Content = nextPage;"

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

public void Navigate(UserControl nextPage)
    {
        this.Dispatcher.Invoke(() =>
        {
        var aa = nextPage.Dispatcher.CheckAccess();

        this.Content = nextPage;
            });
    }

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

1 Ответ

0 голосов
/ 15 мая 2018

WPF очень строго (по сравнению с формами Windows) требует, чтобы методы, которые обновляли элементы пользовательского интерфейса, выполнялись в основном потоке / пользовательском интерфейсе.Таким образом, вы определенно хотите, чтобы оба окна были в основном потоке пользовательского интерфейса.Ошибка, которую вы видите, это то, что происходит, если вы пытаетесь выполнить работу с пользовательским интерфейсом в WPF из другого потока, поэтому вам абсолютно необходимо прекратить это делать.Можно открыть несколько окон, все в одном потоке пользовательского интерфейса.

Если одно из ваших окон выполняет тяжеловесную обработку, которая блокирует пользовательский интерфейс, то проще всего, вероятно, добавить ключевое слово async к вашему.событие нажатия кнопки и поместите работу, которую вы делаете, в другой метод, который имеет ключевое слово async.Затем, когда вы вызываете вспомогательный метод, вы используете ключевое слово await.

Я согласен с другими, что BackgroundWorker и Task - это два других способа выполнения тяжеловесной обработки в фоновом потоке, при этом все еще имея отзывчивый пользовательский интерфейс.Задачи проще в использовании, чем BackgroundWorker.

Если вы используете BackgroundWorker, может быть достаточно использовать событие RunWorkerCompleted.Если это так, посмотрите на этот пост: Как использовать WPF Background Worker .Если вы используете BackgroundWorker и вам нужно вызвать пользовательский метод в своем классе пользовательского интерфейса из фонового потока, то передайте объект Dispatcher для вашего окна / диалога в фоновый поток (или получите доступ к нему другим способом), и когдаон должен перезвонить в пользовательский интерфейс, использовать Invoke с объектом Dispatcher.Используя Invoke, метод, который вы вызываете из фонового потока, будет выполняться в потоке пользовательского интерфейса.

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