C# 调用线程无法访问此对象,因为其他线程拥有它;线程wpf中的错误

C# 调用线程无法访问此对象,因为其他线程拥有它;线程wpf中的错误,c#,wpf,multithreading,C#,Wpf,Multithreading,我有一个窗口1,在这个窗口中单击按钮,我将在新线程中打开窗口2。 下面是我的代码 private void Button_Click_2(object sender, RoutedEventArgs e) { Thread thread = new Thread(() => { Scanner w = new Scanner(); w.Show(); w.Closed +=

我有一个窗口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上单击按钮时,我正在将窗体的值传递给另一个视图

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;”处出现错误

调用线程无法访问此对象,因为其他线程拥有它

我见过其他开发人员提出类似的问题,但我不知道如何解决。 请帮助

与Windows窗体相比,WPF要求在主/UI线程上更新UI元素的方法非常严格。因此,您肯定希望两个窗口都位于主/UI线程中。您看到的错误是,如果您尝试从不同的线程在WPF中执行UI工作,那么会发生什么,因此您必须停止这样做。可以打开多个窗口,所有窗口都在同一个UI线程上

如果您的某个窗口正在执行重量级处理,从而导致UI锁定,那么最简单的方法可能是将async关键字添加到按钮单击事件中,并将您正在执行的工作放在另一个具有async关键字的方法中。然后,在调用helper方法时,使用wait关键字

我同意其他人的观点,BackgroundWorker和Task是在后台线程中完成重量级处理的另外两种方法,同时仍然具有响应性UI。任务比BackgroundWorker更容易使用


如果您使用的是BackgroundWorker,那么可以使用RunWorkerCompleted事件。如果是这样,请查看以下帖子:。如果您正在使用BackgroundWorker,并且需要从后台线程调用UI类中的自定义方法,则将窗口/对话框的Dispatcher对象传递给后台线程(或者以其他方式访问它),当它需要回调到UI中时,使用Invoke和Dispatcher对象。通过使用Invoke,后台线程调用的方法将在UI线程上执行。

是否有任何理由在其他UI线程中启动第二个窗口?除此之外,它让你的生活更艰难,它有什么好处?最好在BackgroundWorker中进行后台处理,或者使用任务。@Clemens实际上我希望用户在窗口2中输入详细信息,基于此,我希望在运行时将更改反映到窗口1。是否可以使用BackgroundWorker和任务?即使没有这些。只需创建第二个窗口实例并调用Show()。一个WPF应用程序可以有多个窗口,所有窗口都由同一个UI线程操作。@Jack正如Clemens指出的,您可以调用show()。ui将为您处理线程。你很少需要自己做这件事。至于实时更改,可以通过多种方式轻松处理。如果不知道需要进行哪些更改,我无法提供特定的解决方案,但第一步是不要让自己的线程只是调用show。然后您可以决定如何将消息传递回“父”窗口。@破解“ui将为您处理线程”的含义是什么?只有一个UI线程可以处理多个顶级窗口,仅此而已。不涉及其他“线程”。
public void Navigate(UserControl nextPage)
    {
        this.Dispatcher.Invoke(() =>
        {
        var aa = nextPage.Dispatcher.CheckAccess();

        this.Content = nextPage;
            });
    }