多线程 - 窗口首先关闭,然后创建,即使在代码中首先调用创建方法

本文关键字:创建 方法 调用 代码 然后 窗口 多线程 | 更新日期: 2023-09-27 18:30:22

这是我执行的代码:

OpenMyWindowInNewThread(1280, 1024, 5);
//do some stuff
CloseMyWindow();

以下是方法:

public void OpenMyWindowInNewThread(int width, int height, int top)
    {
        thread = new Thread(x => OpenMyWindow(width, height, top));
        thread.IsBackground = true;
        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();
    }
    public void CloseMyWindow()
    {
        if (myWindow != null)
        {
            myWindow.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() =>
            {
                myWindow.Close();
                myWindow = null;
            }));
        }
    }
private void OpenMyWindow(int width, int height, int top)
    {
        myWindow = new MyView();
        myWindow.Closed += new EventHandler(MyWindow_Closed);
        myWindow.Width = width;
        myWindow.Height = height;
        myWindow.Top = top;
        myWindow.Left = 0;
        myWindow.ShowDialog();
    }

当我第一次调用第一个代码时,屏幕会显示并关闭,这是应该的。但是,当我第二次执行代码时,会发生以下情况:首先调用 OpenMyWindowInNewThread(),然后调用 OpenMyWindow(),然后调用 CloseMyWindow() 方法中的 if 条件,然后调用 OpenMyWindow() 方法中的 MyView() 构造函数。因此,窗口永远不会关闭,因为首先它是关闭的,然后是创建的。

为什么会这样?有人可以解释一下吗?

多线程 - 窗口首先关闭,然后创建,即使在代码中首先调用创建方法

问题是您有两个线程访问窗口;关闭窗口的线程在执行打开的线程完成其操作之前运行 close 方法。解决此问题的最简单方法是锁定窗口的打开和关闭。如前所述,多个 UI 线程并不是一个简单的概念,它可能会变得非常非常混乱!

private static object _syncLock = new object();
public void CloseMyWindow()
{
    lock(_syncLock)
    {
        if (myWindow != null)
        {
            myWindow.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() =>
            {
                myWindow.Close();
                myWindow = null;
            }));
        }
    }
}
private void OpenMyWindow(int width, int height, int top)
{
    lock(_syncLock)
    {
        myWindow = new MyView();
        myWindow.Closed += new EventHandler(MyWindow_Closed);
        myWindow.Width = width;
        myWindow.Height = height;
        myWindow.Top = top;
        myWindow.Left = 0;
        myWindow.ShowDialog();
    }
}