跳出三界外,不在五行中的timer: private void button1_Click(object sender, EventArgs e) { System.Timers.Timer t = new System.Timers.Timer(); t.Interval = 1000 * 2; t.Elapsed += delegate { MessageBox.Show(System.DateTime.Now.ToString()); }; t.Start(); } 按完button1按钮后,timer持续运行,每隔约2秒就会弹出一个msgbox显示当前时间,当然,因为我们已经失去了t这个变量,表面上也就无法终止这个timer了(也许有办法终止吧)。对于这种现象,我推测是三种原因造成的。一,timer是对windows内核对象的包装,上面这段托管代码的底层调用了来自windows的一些内核对象,在超离作用域的时候,没有对内核对象进行相应的处理,当然这只是推测,我现在没有精力去证实。其二:委托原因。其三 :使用了多线程技术。 private void button2_Click(object sender, EventArgs e) { System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(delegate() { for (int i = 0; i < 6; i++) { System.Threading.Thread.Sleep(3000); MessageBox.Show("I'm in thread"); } })); t.Start(); MessageBox.Show("end of click"); }
以上两段代码,现象是类似的,我将其称之为游魂现象——看上变量已经死了,实际上依然存在,原理尚有待研究。 private void button1_Click(object sender, EventArgs e) { System.Timers.Timer t = new System.Timers.Timer(); t.Interval = 1000 * 2; t.Elapsed += delegate { MessageBox.Show(System.DateTime.Now.ToString()); }; t.Start(); System.Threading.Thread.Sleep(1000 * 20); t.Stop(); } using的法力? private void button4_Click(object sender, EventArgs e) { using (System.Timers.Timer t = new System.Timers.Timer()) { t.Interval = 1000 * 1; t.Elapsed += delegate { MessageBox.Show(System.DateTime.Now.ToString()); }; t.Start(); } System.Threading.Thread.Sleep(1000 * 20); } 2.再看以下代码
private void button4_Click(object sender, EventArgs e) { using (System.Timers.Timer t = new System.Timers.Timer()) { t.Interval = 1000 * 1; t.Elapsed += delegate { MessageBox.Show(System.DateTime.Now.ToString()); }; t.Start(); System.Threading.Thread.Sleep(1000 * 5); } } private void button3_Click(object sender, EventArgs e)
{ GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); MessageBox.Show("Collect function invok complete."); } |
|