c# - 使用另一个线程在 WPF 中创建新窗口时的奇怪行为

标签 c# wpf multithreading

我正在尝试在 WPF 中制作一个简单的应用程序,它将在一个行为异常的线程中打开一个新窗口。

ArrayList formArray = new ArrayList();
Thread th;
Window1 vd;

public void Start()
{
    vd = new Window1();

    formArray.Add(vd);
    vd.ShowDialog();
}

public void StartCall()
{
    th = new Thread(new ThreadStart(Start));
    th.SetApartmentState(ApartmentState.STA);
    th.Start();
}

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    StartCall();
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    ((Window1)(formArray[0])).Show();
}

Window1代码是

private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    e.Cancel = true;
    this.Hide();
}

当试图再次打开它时,它只是抛出一个错误调用线程无法访问这个对象,因为另一个线程拥有它

当尝试使用调度程序时...调用...所有这些都没有帮助。 更奇怪的是,同样的代码在 Windows 窗体应用程序中运行。

也许与这条线有关? th.SetApartmentState(ApartmentState.STA);?

可能是这些家伙,但如果我不添加它,它也会失败并出现错误

附加信息:调用线程必须是 STA,因为很多 UI 组件都需要这个。

最佳答案

编辑: 在您的线程上添加了调度程序上的强制运行。 我还添加了一个 Display 方法来根据调用的调度员显示对话框。希望有所帮助!

此外,如此处所述:Dispatcher.Run

完成后应关闭相应线程的调度程序。

主窗口:

    void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        StartCall();
    }

    ArrayList formArray = new ArrayList();
    Window1 vd;
    Thread th;

    public void Start()
    {
        vd = new Window1();
        formArray.Add(vd);
        vd.ShowDialog();

        System.Windows.Threading.Dispatcher.Run(); //ok this is magic
    }

    public void StartCall()
    {
        th = new Thread(new ThreadStart(Start));
        th.SetApartmentState(ApartmentState.STA);
        th.Start();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        StartCall();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        ((Window1)(formArray[0])).Display();            
    }

窗口 1:

    void Window1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
        e.Cancel = true;
        this.Hide();
    }

    public void Display()
    {
        if (!Dispatcher.CheckAccess())
        {
            Dispatcher.BeginInvoke((Action)Display);
            return;
        }

        this.Show();
    }

关于c# - 使用另一个线程在 WPF 中创建新窗口时的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30101496/

相关文章:

c# - 检查我的 WPF WebBrowser 中的元素,使用 "inspect element(s)"(IE、Chrome、Firefox)获取 css 路径 ("copy css-path")

Linux环境,定时器回调与应用线程的同步

c# - "Include"扩展方法不适用于 LinqKit

c# - 使用 SqlBulkCopy 填充非常大的表的最佳方法是什么?

c# - 在 Visual Studio 中将应用程序移动到另一台计算机时复制数据库文件

android - Realm 实例和多线程

java - 将 ThreadFactory 传递给 ScheduledThreadPoolExecutor

c# - 如何配置 XmlDocument

c# - View Model Locator 的用途是什么?

c# - 防止在测量阶段调用 ApplyTemplate()