我不知道这怎么可能。请帮忙!!

我有一个带有trayicon的应用程序。我希望当用户双击任务栏图标时显示一个表单。我有一个问题,可以通过快速单击托盘图标三重或四重来显示2个或更多表单。我不希望单例的原因是我希望每次关闭窗体都可以释放该窗体以节省内存,也许这不是一个好主意吗?

我有一个名为m_form1的字段。
我有一个叫做ShowForm1的方法;
我双击TrayIcon调用方法ShowForm1。

        private Form1 m_form1;
        private void ShowForm1()
        {
            if (m_form1 == null)
            {
                Trace.WriteLine("*CREATE*" + Thread.CurrentThread.ManagedThreadId.ToString());
                m_form1 = new Form1();
                m_form1.FormClosed += new FormClosedEventHandler(m_form1_FormClosed);
                m_form1.Show();
            }
            m_form1.BringToFront();
            m_form1.Activate();
        }

因此,当Form1需要一些时间来构造时,可以创建2,因为当第二个调用到达时m_form1仍然为null。锁定似乎不起作用,因为两个调用都是同一线程(我猜是UI线程),即跟踪将* CREATE * 1两次写出(如下)。
[3560] *CREATE*1
[3560] *CREATE*1

更改代码以包含lock语句对我没有帮助。
    private Form1 m_form1;
    private object m_Locker = new object();
    private void ShowForm1()
    {
        lock (m_Locker)
        {
            if (m_form1 == null)
            {
                Trace.WriteLine("****CREATE****" + Thread.CurrentThread.ManagedThreadId.ToString());
                m_form1 = new Form1();
                m_form1.FormClosed += new FormClosedEventHandler(m_form1_FormClosed);
                m_form1.Show();
            }
        }
        m_form1.BringToFront();
        m_form1.Activate();
    }

我应该如何处理这种情况?

谢谢你们

蒂姆

最佳答案

还有一个 bool 变量“m_formUnderConstruction”,您可以在构造表单之前对其进行测试,并在决定构造表单后立即对其进行设置。

不幸的是,重新进入使所有这些变得有些棘手。我已经删除了锁,就好像曾经从不同的线程调用过该锁一样,那么您就很讨厌尝试显示一种形式,该形式从不同的线程到构造该线程的线程。

private Form1 m_form1;
private bool m_underConstruction = false;

private void ShowForm1()
{
    if (m_underConstruction)
    {
        // We're about to show it anyway
        return;
    }
    m_underConstruction = true;
    try
    {
        if (m_form1 == null)
        {
            m_form1 = new Form1();
            m_form1.FormClosed += new FormClosedEventHandler(m_form1_FormClosed);
            m_form1.Show();
        }
    }
    finally
    {
        m_underConstruction = false;
    }
    m_form1.BringToFront();
    m_form1.Activate();
}

关于c# - 单实例形式,但不单例,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/270091/

10-15 10:40