欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
.NET中的三種Timer的區別和用法
最近正好做一個(gè)WEB中定期執行的程序,而.NET中有3個(gè)不同的定時(shí)器。所以正好研究研究。這3個(gè)定時(shí)器分別是:
//1.實(shí)現按用戶(hù)定義的時(shí)間間隔引發(fā)事件的計時(shí)器。此計時(shí)器最宜用于 Windows 窗體應用程序中,并且必須在窗口中使用。
System.Windows.Forms.Timer
// 2.提供以指定的時(shí)間間隔執行方法的機制。無(wú)法繼承此類(lèi)。
System.Threading.Timer
//3.在應用程序中生成定期事件。
System.Timers.Timer
這三個(gè)定時(shí)器位于不同的命名空間內,上面大概介紹了3個(gè)定時(shí)器的用途,其中第一個(gè)是只能在Windows窗體中使用的控件。在.NET1.1里面,第3個(gè)System.Timers.Timer,也是可以拖拽使用,而.NET2.0開(kāi)始取消了,只能手動(dòng)編寫(xiě)代碼。而后2個(gè)沒(méi)有限制制。下面通過(guò)具體的列子來(lái)看3個(gè)Timer的使用和區別,網(wǎng)上談的很多,但基本都沒(méi)有代碼。
一 System.Windows.Forms.Timer
#region System.Windows.Forms.Timer
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
int num = 0;
private void Form_Timer_Tick(object sender, EventArgs e)
{
label1.Text = (++num).ToString();
Thread.Sleep(3000);
}
private void button1_Click(object sender, EventArgs e)
{
Form_Timer.Start();
}
private void button2_Click(object sender, EventArgs e)
{
Form_Timer.Stop();
}
}
#endregion
上面這個(gè)是一個(gè)很簡(jiǎn)單的功能,在Form窗體上拖了一個(gè)System.Windows.Forms.Timer控件名字為Form_Timer,在屬性窗中把Enable屬性設置為T(mén)ure,Interval是定時(shí)器的間隔時(shí)間。雙擊這個(gè)控件就可以看到 Form_Timer_Tick方法。在這個(gè)方法中,我們讓她不停的加一個(gè)數字并顯示在窗體上,2個(gè)按鈕提供了對計時(shí)器的控制功能。
執行的時(shí)候你去點(diǎn)擊其他窗體在回來(lái),你會(huì )發(fā)現我們的窗體失去響應了。因為我們這里使用Thread.Sleep(3000);讓當前線(xiàn)程掛起,而UI失去相應,說(shuō)明了這里執行時(shí)候采用的是單線(xiàn)程。也就是執行定時(shí)器的線(xiàn)程就是UI線(xiàn)程。
Timer 用于以用戶(hù)定義的事件間隔觸發(fā)事件。Windows 計時(shí)器是為單線(xiàn)程環(huán)境設計的,其中,UI 線(xiàn)程用于執行處理。它要求用戶(hù)代碼有一個(gè)可用的 UI 消息泵,而且總是在同一個(gè)線(xiàn)程中操作,或者將調用封送到另一個(gè)線(xiàn)程。
在Timer內部定義的了一個(gè)Tick事件,我們前面雙擊這個(gè)控件時(shí)實(shí)際是增加了一行代碼
this.Form_Timer.Tick += new System.EventHandler(this.Form_Timer_Tick);
這個(gè)應該明白,不明白的可以看我BLOG中有關(guān)委托和事件的文章。然后Windows將這個(gè)定時(shí)器與調用線(xiàn)程關(guān)聯(lián)(UI線(xiàn)程)。當定時(shí)器觸發(fā)時(shí),Windows把一個(gè)定時(shí)器消息插入到線(xiàn)程消息隊列中。調用線(xiàn)程執行一個(gè)消息泵提取消息,然后發(fā)送到回調方法中(這里的Form_Timer_Tick方法)。而這些都是單線(xiàn)程進(jìn)行了,所以在執行回調方法時(shí)UI會(huì )假死。所以使用這個(gè)控件不宜執行計算受限或IO受限的代碼,因為這樣容易導致界面假死,而應該使用多線(xiàn)程調用的Timer。另外要注意的是這個(gè)控件時(shí)間精度不高,精度限定為 55 毫秒。我們把Interval設置為20ms,然后在start和stop方法中記錄當前時(shí),并計算出運行時(shí)間:
從上面圖可以看到程序執行了7.8S也就是 7800ms,而間隔時(shí)間是20ms,也就是最后顯示數字應該是390左右,但只有250,顯然是不準確的,不過(guò)按MSDN說(shuō)的55ms的精度,7800ms應該只執行了140多次或更少。不知道這里是不是理解有問(wèn)題。
二 System.Timers.Timer
接下來(lái)就看下另一個(gè)Timer,我們用他來(lái)改寫(xiě)上面的程序
#region System.Windows.Forms.Timer
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
int num = 0;
DateTime time1 = new DateTime();
DateTime time2 = new DateTime();
//定義Timer
System.Timers.Timer Timers_Timer = new System.Timers.Timer();
private void button1_Click(object sender, EventArgs e)
{
//手動(dòng)設置Timer,開(kāi)始執行
Timers_Timer.Interval = 20;
Timers_Timer.Enabled = true;
Timers_Timer.Elapsed += new System.Timers.ElapsedEventHandler(Timers_Timer_Elapsed);
time1 = DateTime.Now;
}
void Timers_Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
label1.Text = Convert.ToString((++num)); //顯示到lable
Thread.Sleep(3000);
}
private void button2_Click(object sender, EventArgs e)
{
//停止執行
Timers_Timer.Enabled = false;
time2 = DateTime.Now;
MessageBox.Show(Convert.ToString(time2-time1));
}
}
#endregion
我們可以看到這個(gè)代碼和前面使用Form.Timer的基本相同,不同的是我們是手動(dòng)定義的對象,而不是通過(guò)拉控件。他也有Interval ,Enabled 等屬性,作用和第一是一樣的。不同的是他的事件名為Elapsed ,但是和上面的Tick一樣,綁定一個(gè)委托的方法。只是這里我們是手動(dòng)完成的。另外不同之處是Form.Timer我們可以用Stop和Start方法控制,而這里是通過(guò)Enable屬性控制。但實(shí)際上也可以用Stop和Start方法,內部也是通過(guò)他自己的Enable來(lái)控制的。
最大的不同就是上面的代碼在調試時(shí)會(huì )報錯,提示你"線(xiàn)程間操作無(wú)效: 從不是創(chuàng )建控件“label1”的線(xiàn)程訪(fǎng)問(wèn)它。"但如果你不調試直接運行是OK的,而且運行時(shí)你去拖動(dòng)窗體會(huì )發(fā)現沒(méi)有出現假死。從這里我們就可以知道這里的Timer的創(chuàng )建線(xiàn)程和執行線(xiàn)程不是同一個(gè)線(xiàn)程。也就是使用了多線(xiàn)程。Timer的創(chuàng )建線(xiàn)程是UI線(xiàn)程,而執行線(xiàn)程是TheardPool中的線(xiàn)程,所以不會(huì )假死,但調試的時(shí)候會(huì )報錯,因為非控件的創(chuàng )建線(xiàn)程不能操作控件。但你可以直接運行,這里是VS05做了手腳。解決辦法很多,用delegate.BeginInvoke()等等。這里介紹特有的一種方法,設置Timer的SynchronizingObject屬性,Timers_Timer.SynchronizingObject = label1;這樣的話(huà),我們的話(huà),調試運行時(shí)就不會(huì )報錯了,但是設置了這個(gè)屬性Timer就編程單線(xiàn)程調用了,就基本和第一個(gè)完全一樣了。
Timer 是為在多線(xiàn)程環(huán)境中用于輔助線(xiàn)程而設計的。服務(wù)器計時(shí)器可以在線(xiàn)程間移動(dòng)來(lái)處理引發(fā)的 Elapsed 事件,這樣就可以比 Windows 計時(shí)器更精確地按時(shí)引發(fā)事件。Elapsed 事件在 ThreadPool 線(xiàn)程上引發(fā)。如果 Elapsed 事件的處理時(shí)間比 Interval 長(cháng),在另一個(gè) ThreadPool 線(xiàn)程上將會(huì )再次引發(fā)此事件。因此,事件處理程序應當是可重入的。
另外和前面不同的現象是每次加1后并沒(méi)有停止3秒在顯示。而是繼續顯示,只是速度稍慢。因為我們設置間隔為20ms,而執行時(shí)間為3s,所以會(huì )在20ms后在另一個(gè)線(xiàn)程中繼續執行,而當前線(xiàn)程被掛起而已。關(guān)于計時(shí)器的精度,取消3s的掛起,發(fā)現結果和第一個(gè)基本一致。
三 System.Threading.Timer
繼續用這個(gè)對象改造程序。
#region System.Windows.Forms.Timer
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
int num = 0;
DateTime time1 = new DateTime();
DateTime time2 = new DateTime();
System.Threading.Timer Thread_Time;
private void button1_Click(object sender, EventArgs e)
{
//啟動(dòng)
Thread_Time = new System.Threading.Timer(Thread_Timer_Method,null,0,20);
time1 = DateTime.Now;
}
void Thread_Timer_Method(object o)
{
label1.Text = Convert.ToString((++num));
System.Threading.Thread.Sleep(3000);
}
private void button2_Click(object sender, EventArgs e)
{
//停止
Thread_Time.Dispose();
time2 = DateTime.Now;
MessageBox.Show(Convert.ToString(time2-time1));
}
}
#endregion
用Threading.Timer時(shí)的方法,和前面就不太相同了,所以的參數全部在構造函數中進(jìn)行了設置,而且可以設置啟動(dòng)時(shí)間。而且沒(méi)有提供start和stop方法來(lái)控制計時(shí)器。而且是以一種回調方法的方式實(shí)現,而不是通過(guò)事件來(lái)實(shí)現的。他們之間還是有區別的。
我們只有銷(xiāo)毀掉對象來(lái)停止他。當你運行時(shí),你會(huì )發(fā)現他和前面的Timers.Timer一樣,是多線(xiàn)程的,主要表現在不會(huì )假死,調試運行報錯。但跟讓你奇怪的是,我們的代碼竟然無(wú)法讓她停止下來(lái)。調用了Dispose方法沒(méi)有用。問(wèn)題在那?然后有進(jìn)行了測試,修改了間隔時(shí)間為100,200,500,1000,3000,4000。這幾種情況。發(fā)現當間隔為500ms以上是基本馬上就停止了。而間隔時(shí)間相對執行時(shí)間越短,繼續執行的時(shí)間越長(cháng)。這應該是在間隔時(shí)間小于執行時(shí)間時(shí)多個(gè)線(xiàn)程運行造成的。因為所有的線(xiàn)程不是同時(shí)停止的。間隔越短,線(xiàn)程越多,所以執行次數越多。
最后來(lái)看下這個(gè)對象另外一個(gè)特殊的地方。
static void Main()
{
Timer t = new Timer(Test,null,0,1000);
Console.ReadLine();
}
public static void Test(object o)
{
Console.WriteLine("nihao");
GC.Collect();
}
這段代碼會(huì )輸出什么結果呢?默認情況他只輸出一次,就停止了。為什么呢?根據上面說(shuō)的,當定義對象t,執行代碼后,進(jìn)行了強制垃圾回收,因為t在Main中沒(méi)有其他引用,所以被回收掉了。但是如果我們吧編譯器的”優(yōu)化“項取消掉,在看看情況。程序進(jìn)然一直在輸出。為什么執行垃圾回收卻沒(méi)有被回收呢?因為這個(gè)禁用優(yōu)化選項,t的聲明周期被擴展到了方法結束。所以一直執行。
因為編譯器默認是優(yōu)化的,所以我們必須保證Timer對象一直被引用,而避免被垃圾回收。所以我們可以在編譯器打開(kāi)優(yōu)化的情況下,在Main函數最后加上t=null保證回收前被引用,但你發(fā)現,這樣是沒(méi)用的。因為JIT編譯器優(yōu)化后會(huì )吧t=null直接刪除,所以我們用t.Dispose(),就可以達到目的。在我們進(jìn)行垃圾回收時(shí),CLR發(fā)現t還有被引用,還沒(méi)執行Dispose所以不會(huì )被回收。是以Threading.Timer有時(shí)候會(huì )出現運行一次就停止或者是銷(xiāo)毀了還在運行的情況,而且和編譯器優(yōu)化也有關(guān),所以使用時(shí)要注意。
最后看下MSDN的描述: 只要在使用 Timer,就必須保留對它的引用。對于任何托管對象,如果沒(méi)有對 Timer 的引用,計時(shí)器會(huì )被垃圾回收。即使 Timer 仍處在活動(dòng)狀態(tài),也會(huì )被回收。當不再需要計時(shí)器時(shí),請使用 Dispose 方法釋放計時(shí)器持有的資源。如果希望在計時(shí)器被釋放時(shí)接收到信號,請使用接受 WaitHandle 的 Dispose(WaitHandle) 方法重載。計時(shí)器已被釋放后,WaitHandle 便終止。
總結:
System.Threading.Timer 是一個(gè)簡(jiǎn)單的輕量計時(shí)器,它使用回調方法并由線(xiàn)程池線(xiàn)程提供服務(wù)。不建議將其用于 Windows 窗體,因為其回調不在用戶(hù)界面線(xiàn)程上進(jìn)行。System.Windows.Forms.Timer 是用于 Windows 窗體的更佳選擇。要獲取基于服務(wù)器的計時(shí)器功能,可以考慮使用 System.Timers.Timer,它可以引發(fā)事件并具有其他功能。
在《CLR Via C#》中講多線(xiàn)程時(shí)有提到這3個(gè)計時(shí)器,但作者說(shuō)System.Timers.Timer是對System.Threading.Timer的報裝,不推薦使用,但是在我的WEB項目中的Application_Start中我還是使用的這個(gè)而不是Threading.Timer,因為使用Threading.Timer時(shí)只執行了一次就不在執行了。
對于計時(shí)器在B/S結構中的使用就復雜一些,一般我們把計時(shí)器放在A(yíng)pplication_OnStart中,這樣全局維護一個(gè)計時(shí)器,可以進(jìn)行定期備份數據庫,定期維護用戶(hù)等操作,而且方法寫(xiě)作靜態(tài)的,以免被垃圾回收。而不建議在一般的aspx頁(yè)面中使用,因為服務(wù)器端的定時(shí)器對用戶(hù)這樣意義不大,完全可以使用JS代替。而且這個(gè)頁(yè)面的每個(gè)請求都可能引入一個(gè)新的定時(shí)器,導致系統崩潰。另外,定時(shí)器是ASP.NET進(jìn)程,IIS有關(guān),所以對用重要的執行任務(wù),還是建議寫(xiě)成服務(wù)或獨立程序放在服務(wù)器上執行好了。
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
System.Windows.Forms.Timer、System.Timers.Timer、System.Threading.Timer的 區別和用法
C#各種定時(shí)器比較
c# 中定時(shí)器的用法
python定時(shí)器
.NET中的四個(gè)Timer
@開(kāi)發(fā)者,一文搞懂什么是 C# 計時(shí)器!
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久