创建一个WinForm程序.自带一个Form1.在Form1上放置一个button1
创建一个UserControl控件,在控件上放置一个button1,
把创建好的控件放置到 Form1上,名称为 UserControl1
Form1代码如下:
public
partial
class
Form1 : Form
... {
public Form1()
...{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
...{
lock (userControl1.FLAG)
...{
System.Diagnostics.Debug.WriteLine("button1_Click Locked.");
userControl11.Dispose();
}
System.Diagnostics.Debug.WriteLine("button1_Click Locked.OUT");
}
}
... {
public Form1()
...{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
...{
lock (userControl1.FLAG)
...{
System.Diagnostics.Debug.WriteLine("button1_Click Locked.");
userControl11.Dispose();
}
System.Diagnostics.Debug.WriteLine("button1_Click Locked.OUT");
}
}
UserControl代码如下:
public
partial
class
UserControl1 : UserControl
... {
public object FLAG = new object();
System.Timers.Timer m_timer = new System.Timers.Timer(500);
public UserControl1()
...{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
...{
m_timer.Elapsed += new System.Timers.ElapsedEventHandler(m_timer_Elapsed);
m_timer.Start();
}
delegate void dlgtGen();
void m_timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
...{
m_timer.Stop();
this.Invoke(new dlgtGen(AddUC)); //注释这段代码,换成 AddUC();试一下:)
}
void AddUC()
...{
lock (FLAG)
...{
System.Diagnostics.Debug.WriteLine("AddUC Locked.");
for (int i = 0; i < 10000; ++i)
...{
for (int j = 0; j < 1000000; ++j)
...{
//System.Threading.Thread.Sleep(1);
//Application.DoEvents();
}
}
}
System.Diagnostics.Debug.WriteLine("AddUC Locked.END");
}
}
... {
public object FLAG = new object();
System.Timers.Timer m_timer = new System.Timers.Timer(500);
public UserControl1()
...{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
...{
m_timer.Elapsed += new System.Timers.ElapsedEventHandler(m_timer_Elapsed);
m_timer.Start();
}
delegate void dlgtGen();
void m_timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
...{
m_timer.Stop();
this.Invoke(new dlgtGen(AddUC)); //注释这段代码,换成 AddUC();试一下:)
}
void AddUC()
...{
lock (FLAG)
...{
System.Diagnostics.Debug.WriteLine("AddUC Locked.");
for (int i = 0; i < 10000; ++i)
...{
for (int j = 0; j < 1000000; ++j)
...{
//System.Threading.Thread.Sleep(1);
//Application.DoEvents();
}
}
}
System.Diagnostics.Debug.WriteLine("AddUC Locked.END");
}
}
运行程序后,先点击 控件上的BUTTON,再点击FORM1上的BUTTON,看看会有什么结果?
实际情况是:点击了控件上的BUTTON后,程序处理假死状态,没有反应.因为控件处于主线程内,timer中调用的委托占用了主线程的资源. 当然界面上的资源也是主线程的资源,所以,只有等待委托调用结束后,界面的资源才会有反应.
这其实就如点击一个BUTTON,在BUTTON中Sleep()一段时间效果是一样的!
然后再把
this.Invoke(new dlgtGen(AddUC)); //注释这段代码,换成 AddUC();试一下:)
这行替换为
AddUC();
运行的结果则完成不同了,因为这时候运行的资源完全是主线程之外的一个线程中