【问题标题】:WPF Recreation window in different STA thread不同STA线程中的WPF Recreation窗口
【发布时间】:2017-01-25 17:32:54
【问题描述】:

当我的主窗口正在渲染时,我需要创建带有加载 gif 的窗口。我已经阅读了一些文章并决定为此我需要创建新线程。我在this article 中做到了

结果我有类似的东西:

LoadingDialog _loadingDlg;
Thread loadingThread;

public void ShowLoading()
{
    loadingThread = new Thread(new ThreadStart(loadingThreadWork));
    loadingThread.SetApartmentState(ApartmentState.STA);
    loadingThread.Start();
}

private void loadingThreadWork()
{
    _loadingDlg = new LoadingDialog();
    _loadingDlg.Show();
    System.Windows.Threading.Dispatcher.Run();
}

public void HideLoading()
{
    _loadingDlg.Dispatcher.InvokeShutdown();
}

当我第一次打电话给ShowLoading()HideLoading() 时,一切都如我所愿。但是当我第二次拨打ShowLoading() 时,我在

_loadingDlg.Show();

带有消息The calling thread cannot access this object because a different thread owns it

这怎么可能? _loadingDlg 是在上一行中创建的,并且在同一个线程中。

【问题讨论】:

  • 为什么要新建一个窗口?为什么不直接制作一个居中的网格,并且可以切换可见性?

标签: c# wpf multithreading dispatcher sta


【解决方案1】:

loadingThreadWork 中,您正在创建控件,在第一次运行之前它是null,因此您第一次成功。但是,您正在另一个线程中创建对话框,该线程被标记为控件的所有者。

下次您调用 loadingThreadWork 时,控件不为空,并且 ant 从不同的线程更改它(它是不同的线程,因为您再次创建它)导致你有例外。

当您使用WPF 时,您可能应该从线程切换到async 操作,这比您当前的解决方案更具可读性、可支持性和可预测性。

【讨论】:

  • 谢谢。有了你的话,我找到了解决问题的方法。所有者是为班级而不是例如确定的,这对吗?当我可以阅读有关此的更多详细信息时,您能否提供一些文章。
  • 不,所有者由实例确定。您可以按消息错误搜索,这是一个常见的错误。
  • 但是使用新线程我重新创建了一个实例。在此之后我得到异常。
猜你喜欢
  • 1970-01-01
  • 2012-09-09
  • 2011-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-24
  • 2012-04-22
相关资源
最近更新 更多