Tim*_*ley 1 c# multithreading winforms
我无法理解这是如何可能的.请帮忙!!
我有一个带有trayicon的应用程序.我希望在用户双击trayicon时显示一个表单.我有一个问题,可以通过快速三次或四次点击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();
}
Run Code Online (Sandbox Code Playgroud)
因此,当Form1需要一段时间来构造时,则可以创建2,因为当第二个调用到达时m_form1仍然为null.锁定似乎不起作用,因为它是同一个线程两个调用(我猜的是UI线程),即跟踪写出*CREATE*1两次(下面).
[3560] *CREATE*1
[3560] *CREATE*1
Run Code Online (Sandbox Code Playgroud)
更改代码以包含锁定语句对我没有帮助.
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();
}
Run Code Online (Sandbox Code Playgroud)
我该如何处理这种情况?
多谢你们
蒂姆.
有一个额外的布尔变量,"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();
}
Run Code Online (Sandbox Code Playgroud)