总结以下三种方法,实现c#每隔一段时间执行代码:

方法一:调用线程执行方法,在方法中实现死循环,每个循环Sleep设定时间;

方法二:使用System.Timers.Timer类;

方法三:使用System.Threading.Timer;

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());
    }
}

参考:

http://www.cnblogs.com/tianzhiliang/archive/2010/08/31/1813928.html

http://www.cnblogs.com/zxtceq/p/5667281.html

================================================================================

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 ;   //任务代码 还是在执行。。。。我想问我怎么做 才可以把这些阻塞了线程立刻释放掉。简单的意思就是立刻停止它?

-----------------------------------------------------------

#16 得分:55回复于: 2008-05-07 19:16:48

LZ是这样的:你的fTimer每秒钟都会调用一次DoTask,且同一时间只会有一个DoTask在运行,如果此时已有一个DoTask在运行,那么后面的将被lock在那里等着
LZ你这么做一是为了同一时间只做一个DoTask,二是为了保证执行的顺序吧?
实际上,当DoTask里的操作超过1秒时,后面的DoTask都会被lock在那里。比如我的fTimer运行了9秒多,那么应该有总共10个DoTask,假设DoTask要执行2秒钟,那么当你在9秒多停止fTimer的时候,实际上才运行到第5个DoTask(左右),后面还有5个DoTask被lock着呢
LZ可以看下这个
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();
}
}
}

-------------------------------------------------

1、下面只解释你的问题,并不是达到你目的的最好方法。

2、Threading.Timer的工作方式是这样的。每次时钟到点时,Timer从线程池中取出一个线程来运行回调函数。如果该回调函数在下次时钟到点前还没来得及结束,那么,可能会有多个线程同时在执行该函数。如果线程池中没有空闲的线程可用,回调函数就要排队等候。

3、Timer被取消后,它就不再安排新的回调函数,但是已经在运行的,或已经在排队的回调函数并没有被取消。所以当你fTimer.Dispose();停止了时间后,任务代码还在执行。

4、改进的方法。首先判断一下当前线程池中剩余可用线程的数目,如果小于一定数量,回调函数立刻返回。这样可以减少排队的回调函数。
其次,设置一个‘工作中’的标志,如果回调函数看到该标志被放倒了,它也应该立刻返回。

5、即使经过如上改进后,Timer被取消后,线程池中线程也不会立刻完成 - 正在做‘任务代码’的那个线程得把任务作完了才有机会观察到‘工作中’标志。不过从这时起,所有回调函数将迅速返回。

6、如果你程序退出了,线程池整个就被停止了,当然你所有的任务代码也就被停止了。如果你的任务代码没有需要清理的东西,这也是一种关闭方式。

    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 < )
{
Thread.Sleep(Math.Min(, - elasped));
}
//任务代码...
}
}

出处:http://bbs.csdn.net/topics/220079236/

以上信息只筛选一部分,查看完整版的可以直接查看出处给出的地址。

最新文章

  1. SVN 安装配置
  2. CSS之显示天气
  3. 服务器程序源代码分析之三:gunicorn
  4. 上传jar包到Apache Archiva本地仓库
  5. [poj2762] Going from u to v or from v to u?(Kosaraju缩点+拓排)
  6. cocos2d-x使用CCClippingNode实现跑马灯
  7. JavaScript 44 Puzzlers
  8. grep 与 find 简单命令
  9. 【BZOJ3669】【Noi2014】魔法森林(Link-Cut Tree)
  10. xcode: 解决 __nw_connection_get_connected_socket_block_invoke 1 Connection has no connected handler
  11. Python开发【第五篇】:模块
  12. MySQL中视图
  13. Faiss教程:索引(2)
  14. iOS中使用RegexKitLite来试用正则表达式
  15. 科学计算三维可视化---Traits介绍
  16. Oracle 快速插入1000万条数据的实现方式
  17. 【软件】chrome设置默认字体
  18. web安全漏洞种类
  19. [转]最全Redis面试题整理
  20. js实现鼠标拖拽

热门文章

  1. 每天一个Linux命令(53)service命令
  2. 通过调节坐标进行jfree图的放大缩小
  3. 混淆Android JAR包的方法
  4. linux驱动的异步通知(kill_fasync,fasync)---- 驱动程序向应用程序发送信号
  5. Python编程-编码、文件处理、函数
  6. JavaWeb Cookie
  7. Docker 数据收集利器:cadvisor
  8. JAVA 使用qq邮箱发送邮件
  9. CCNA 课程 四
  10. java深入探究13-js,ajax