總結如下三種方法,實現c#每隔一段時間執行代碼:html
方法一:調用線程執行方法,在方法中實現死循環,每一個循環Sleep設定時間;c#
方法二:使用System.Timers.Timer類;函數
方法三:使用System.Threading.Timer;post
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
using
System;
using
System.Collections;
using
System.Threading;
public
class
Test
{
public
static
void
Main()
{
Test obj =
new
Test();
Console.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString());
//方法一:調用線程執行方法,在方法中實現死循環,每一個循環Sleep設定時間
Thread thread =
new
Thread(
new
ThreadStart(obj.Method1));
thread.Start();
//方法二:使用System.Timers.Timer類
System.Timers.Timer t =
new
System.Timers.Timer(100);
//實例化Timer類,設置時間間隔
t.Elapsed +=
new
System.Timers.ElapsedEventHandler(obj.Method2);
//到達時間的時候執行事件
t.AutoReset =
true
;
//設置是執行一次(false)仍是一直執行(true)
t.Enabled =
true
;
//是否執行System.Timers.Timer.Elapsed事件
while
(
true
)
{
Console.WriteLine(
"test_"
+ Thread.CurrentThread.ManagedThreadId.ToString());
Thread.Sleep(100);
}
//方法三:使用System.Threading.Timer
//Timer構造函數參數說明:
//Callback:一個 TimerCallback 委託,表示要執行的方法。
//State:一個包含回調方法要使用的信息的對象,或者爲空引用(Visual Basic 中爲 Nothing)。
//dueTime:調用 callback 以前延遲的時間量(以毫秒爲單位)。指定 Timeout.Infinite 以防止計時器開始計時。指定零 (0) 以當即啓動計時器。
//Period:調用 callback 的時間間隔(以毫秒爲單位)。指定 Timeout.Infinite 能夠禁用按期終止。
System.Threading.Timer threadTimer =
new
System.Threading.Timer(
new
System.Threading.TimerCallback(obj.Method3),
null
, 0, 100);
while
(
true
)
{
Console.WriteLine(
"test_"
+ Thread.CurrentThread.ManagedThreadId.ToString());
Thread.Sleep(100);
}
Console.ReadLine();
}
void
Method1()
{
while
(
true
)
{
Console.WriteLine(DateTime.Now.ToString() +
"_"
+ Thread.CurrentThread.ManagedThreadId.ToString());
Thread.CurrentThread.Join(100);
//阻止設定時間
}
}
void
Method2(
object
source, System.Timers.ElapsedEventArgs e)
{
Console.WriteLine(DateTime.Now.ToString() +
"_"
+ Thread.CurrentThread.ManagedThreadId.ToString());
}
void
Method3(Object state)
{
Console.WriteLine(DateTime.Now.ToString() +
"_"
+ Thread.CurrentThread.ManagedThreadId.ToString());
}
}
|
參考:this
http://www.cnblogs.com/tianzhiliang/archive/2010/08/31/1813928.htmlspa
http://www.cnblogs.com/zxtceq/p/5667281.html.net
================================================================================線程
System.Threading.Timer fTimer = new System.Threading.Timer(new TimerCallback(TaskService.DoTask), new AutoResetEvent(false), 0, 1000);
public void DoTask(Object stateInfo)
{
lock (this)
{
//任務代碼
}
}
當我 fTimer.Dispose();//中止了時間後,能夠 任務代碼 還在執行。通過我調式N次發現是在lock裏阻塞了線程。當我
fTimer.Dispose()中止後即便把fTimer = null ; //任務代碼 仍是在執行。。。。我想問我怎麼作 才能夠把這些阻塞了線程馬上釋放掉。簡單的意思就是馬上中止它?code
-----------------------------------------------------------htm
#16 得分:55回覆於: 2008-05-07 19:16:48
using System; using System.Collections.Generic; using System.Text; using System.Threading; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { Test t = new Test(); while (t.Enabled) ; Console.WriteLine("STOPING:" + t.Value); t.Stop(); Console.WriteLine("STOPPED:" + t.Value); Console.ReadLine(); } } public class Test { System.Threading.Timer fTimer; private int i = 0; System.Timers.Timer timer; public int Value { get { return i; } } public bool Enabled { get { return timer.Enabled; } } public Test() { fTimer = new System.Threading.Timer(new TimerCallback(this.DoTask), new AutoResetEvent(false), 0, 1000); timer = new System.Timers.Timer(10000); timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed); timer.Enabled = true; } private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { timer.Enabled = false; } public void DoTask(Object stateInfo) { lock (this) { Console.WriteLine(i++); Thread.Sleep(2000); } } public void Stop() { fTimer.Dispose(); } } }
-------------------------------------------------
一、下面只解釋你的問題,並非達到你目的的最好方法。
二、Threading.Timer的工做方式是這樣的。每次時鐘到點時,Timer從線程池中取出一個線程來運行回調函數。若是該回調函數在下次時鐘到點前還沒來得及結束,那麼,可能會有多個線程同時在執行該函數。若是線程池中沒有空閒的線程可用,回調函數就要排隊等候。
三、Timer被取消後,它就再也不安排新的回調函數,可是已經在運行的,或已經在排隊的回調函數並無被取消。因此當你fTimer.Dispose();中止了時間後,任務代碼還在執行。
四、改進的方法。首先判斷一下當前線程池中剩餘可用線程的數目,若是小於必定數量,回調函數馬上返回。這樣能夠減小排隊的回調函數。
其次,設置一個‘工做中’的標誌,若是回調函數看到該標誌被放倒了,它也應該馬上返回。
五、即便通過如上改進後,Timer被取消後,線程池中線程也不會馬上完成 - 正在作‘任務代碼’的那個線程得把任務做完了纔有機會觀察到‘工做中’標誌。不過從這時起,全部回調函數將迅速返回。
六、若是你程序退出了,線程池整個就被中止了,固然你全部的任務代碼也就被中止了。若是你的任務代碼沒有須要清理的東西,這也是一種關閉方式。
class TaskService { volatile bool running = true; public void DoTask(Object stateInfo) { int threadsLeft, dummy; ThreadPool.GetAvailableThreads(out threadsLeft, out dummy); if (threadsLeft < 2) return; //<---- lock (this) { if (!running) return; //<---- //任務代碼 } } public void test() { using (System.Threading.Timer fTimer = new Timer(new TimerCallback(DoTask), null, 0, 1000)) { Console.ReadLine(); fTimer.Change(0, Timeout.Infinite); running = false; } Console.ReadLine(); } static void Main() { new TaskService().test(); } }
沒有用lock和Timer的方法:
volatile bool running = true; public void DoTasks() { DateTime last = new DateTime(); while (running) { DateTime current = DateTime.Now; int elasped = (int) (current - last).TotalMilliseconds; last = current; if (elasped < 1000) { Thread.Sleep(Math.Min(1000, 1000 - elasped)); } //任務代碼... } }
出處:http://bbs.csdn.net/topics/220079236/
以上信息只篩選一部分,查看完整版的能夠直接查看出處給出的地址。