【问题标题】:Load another window in background; when rendered, close the parent window在后台加载另一个窗口;渲染时关闭父窗口
【发布时间】:2013-07-12 11:04:10
【问题描述】:

我一直试图在一个窗口的背景中加载另一个窗口;就我而言,父窗口充当启动画面

InitWindow I = null;
    public InitWindow()
    {
        InitializeComponent();
        I = this;

        Thread T = new Thread(() =>
        {
            MainWindow M = new MainWindow();
            M.Show();
            M.ContentRendered += M_ContentRendered;
            System.Windows.Threading.Dispatcher.Run();
            M.Closed += (s, e) => M.Dispatcher.InvokeShutdown();

        }) { IsBackground = true, Priority = ThreadPriority.Lowest };

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

    void M_ContentRendered(object sender, EventArgs e)
    {
        I.Close();
    }

其他一切正常,但它会在以下位置引发 Invalid Operation Exception:

I.Close();

调用线程无法访问此对象,因为另一个线程拥有它。

1) 如何切换/同步线程?

2) 有更好的解决方法吗?

【问题讨论】:

  • 对于交互式启动屏幕,我宁愿在后台进行加载和设置,然后在完成后切换窗口的内容...
  • @PatrykĆwiek 你建议我不要使用两个窗口,而应该使用一个窗口?
  • 是的,首先显示内容,加载一些内容,然后将主窗口内容切换到您真正想要显示的内容。当然,这对于 interactive 初始屏幕是有好处的,如果您只有一个图像,那么将构建操作设置为“Splash Screen”,问题就解决了,没有任何魔法。
  • @PatrykĆwiek 感谢您的建议。也许我肯定会尝试一下,这是我最后的手段。但我会花更多时间来找到解决此问题的方法。
  • 我不确定,但窗口是在 GUI 线程中处理的。您应该考虑使用 Dispatcher BeginInvoke 方法来管理关闭事件。

标签: c# wpf multithreading


【解决方案1】:

修改代码为:

    InitWindow I = null;
    Thread C = null;  

    public InitWindow()
    {
        InitializeComponent();
        I = this;
        C = Thread.CurrentThread;  

        Thread T = new Thread(() =>
        {
            MainWindow M = new MainWindow();
            M.Show();
            M.ContentRendered += M_ContentRendered;
            System.Windows.Threading.Dispatcher.Run();
            M.Closed += (s, e) => M.Dispatcher.InvokeShutdown();

        }) { IsBackground = true, Priority = ThreadPriority.Lowest };

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

    void M_ContentRendered(object sender, EventArgs e)
    {
        // Making the parent thread background
        C.IsBackground = true; 
        // foreground the current thread
        Thread.CurrentThread.IsBackground = false;
        // Abort the parent thread
        C.Abort();
    }

目前工作正常,但我认为这不是一个可靠的解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-12
    • 1970-01-01
    • 2012-12-15
    • 1970-01-01
    • 1970-01-01
    • 2014-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多