c#如何在click事件里添加timerpython 定时器 timer吗?这样会不会只在点击的时候执行?

&&&& 打开久违的Live Writer,又已经好久没写博客了,真的太懒了。废话不多说了,直接进入这次博客的主题--。为什么要写这个呢,因为前几天应朋友之邀,想做个&黑客&小工具,功能挺简单就是自动获取剪贴板的内容然后发送邮件,就需要用到Timer来循环获取剪贴板的内容,但是由于到了发送邮件这个功能,使用C#的始终发送不了邮件,以前写过类似发邮件的功能,当时可以用网易的,现在也不能用了,不知道咋回事,只好作罢。在使用Timer中遇到了之前没有想过的问题--重入。
&&&& 首先简单介绍一下timer,这里所说的timer是指的System.Timers.timer,顾名思义,就是可以在指定的间隔是引发事件。官方介绍在,摘抄如下:
Timer 组件是基于服务器的计时器,它使您能够指定在应用程序中引发 Elapsed 事件的周期性间隔。然后可通过处理这个事件来提供常规处理。 例如,假设您有一台关键性服务器,必须每周 7 天、每天 24 小时都保持运行。 可以创建一个使用 Timer 的服务,以定期检查服务器并确保系统开启并在运行。 如果系统不响应,则该服务可以尝试重新启动服务器或通知管理员。
基于服务器的 Timer 是为在多线程环境中用于辅助线程而设计的。 服务器计时器可以在线程间移动来处理引发的 Elapsed 事件,这样就可以比 Windows 计时器更精确地按时引发事件。
&&&& 如果想了解跟其他的timer有啥区别,可以看,里面有详细的介绍,不再多说了(其实我也不知道还有这么多)。那使用这个计时器有啥好处呢?主要因为它是通过.NET Thread Pool实现的、轻量、计时精确、对应用程序及消息没有特别的要求。
&&& 下面就简单介绍一下,这个Timer是怎么使用的,其实很简单,我就采用微软提供的示例来进行测试,直接上代码了:
//Timer不要声明成局部变量,否则会被GC回收
private static System.Timers.Timer aT
public static void Main()
//实例化Timer类,设置间隔时间为10000毫秒;
aTimer = new System.Timers.Timer(10000);
//注册计时器的事件
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
//设置时间间隔为2秒(2000毫秒),覆盖构造函数设置的间隔
aTimer.Interval = 2000;
//设置是执行一次(false)还是一直执行(true),默认为true
aTimer.AutoReset = true;
//开始计时
aTimer.Enabled = true;
Console.WriteLine("按任意键退出程序。");
Console.ReadLine();
//指定Timer触发的事件
private static void OnTimedEvent(object source, ElapsedEventArgs e)
Console.WriteLine("触发的事件发生在: {0}", e.SignalTime);
运行的结果如下,计时蛮准确的:
按任意键退出程序。
触发的事件发生在:
星期五 23:08:51
触发的事件发生在:
星期五 23:08:53
触发的事件发生在:
星期五 23:08:55
触发的事件发生在:
星期五 23:08:57
触发的事件发生在:
星期五 23:08:59
★重入问题重现及分析
&&&& 什么叫重入呢?这是一个有关多线程编程的概念:程序中,多个线程同时运行时,就可能发生同一个方法被多个进程同时调用的情况。当这个方法中存在一些非线程安全的代码时,方法重入会导致数据不一致的情况。Timer方法重入是指使用多线程计时器,一个Timer处理还没有完成,到了时间,另一Timer还会继续进入该方法进行处理。下面演示一下重入问题的产生(可能重现的不是很好,不过也能简单一下说明问题了):
//用来造成线程同步问题的静态成员
private static int outPut = 1;
//次数,timer没调一次方法自增1
private static int num = 0;
private static System.Timers.Timer timer = new System.Timers.Timer();
public static void Main()
timer.Interval = 1000;
timer.Elapsed += TimersTimerH
timer.Start();
Console.WriteLine("按任意键退出程序。");
Console.ReadLine();
/// &summary&
/// System.Timers.Timer的回调方法
/// &/summary&
/// &param name="sender"&&/param&
/// &param name="args"&&/param&
private static void TimersTimerHandler(object sender, EventArgs args)
int t = ++
Console.WriteLine(string.Format("线程{0}输出:{1},
输出时间:{2}", t, outPut.ToString(),DateTime.Now));
System.Threading.Thread.Sleep(2000);
Console.WriteLine(string.Format("线程{0}自增1后输出:{1},输出时间:{2}", t, outPut.ToString(),DateTime.Now));
下面显示一下输出结果:
&&&& 是不是感觉上面输出结果很奇怪,首先是线程1输出为1,没有问题,然后隔了2秒后线程1自增1后输出为2,这就有问题了,中间为什么还出现了线程2的输出?更奇怪的是线程2刚开始输出为1,自增1后尽然变成了3!其实这就是重入所导致的问题。别急,咱们分析一下就知道其中的缘由了。
&&&&& 首先timer启动计时后,开启一个线程1执行方法,当线程1第一次输出之后,这时线程1休眠了2秒,此时timer并没有闲着,因为设置的计时间隔为1秒,当在线程1休眠了1秒后,timer又开启了线程2执行方法,线程2才不管线程1是执行中还是休眠状态,所以此时线程2的输出也为1,因为线程1还在休眠状态,并没有自增。然后又隔了1秒,这时发生同时发生两个事件,线程1过了休眠状态自增输出为2,timer同时又开启一个线程3,线程3输出的为线程1自增后的值2,又过了1秒,线程2过了休眠状态,之前的输出已经是2,所以自增后输出为3,又过了1秒&&我都快晕了,大概就是这意思吧,我想表达的就是:一个Timer开启的线程处理还没有完成,到了时间,另一Timer还会继续进入该方法进行处理。
&&&& 那怎么解决这个问题呢?解决方案有三种,下面一一道来,适应不同的场景,不过还是推荐最后一种,比较安全。
★重入问题解决方案
1、使用lock(Object)的方法来防止重入,表示一个Timer处理正在执行,下一个Timer发生的时候发现上一个没有执行完就等待执行,适用重入很少出现的场景(具体也没研究过,可能比较占内存吧)。
代码跟上面差不多,在触发的方法中加入lock,这样当线程2进入触发的方法中,发现已经被锁,会等待锁中的代码处理完在执行,代码如下:
private static object locko = new object();
/// &summary&
/// System.Timers.Timer的回调方法
/// &/summary&
/// &param name="sender"&&/param&
/// &param name="args"&&/param&
private static void TimersTimerHandler(object sender, EventArgs args)
int t = ++
lock (locko)
Console.WriteLine(string.Format("线程{0}输出:{1},
输出时间:{2}", t, outPut.ToString(), DateTime.Now));
System.Threading.Thread.Sleep(2000);
Console.WriteLine(string.Format("线程{0}自增1后输出:{1},输出时间:{2}", t, outPut.ToString(), DateTime.Now));
执行结果:
2、设置一个标志,表示一个Timer处理正在执行,下一个Timer发生的时候发现上一个没有执行完就放弃(注意这里是放弃,而不是等待哦,看看执行结果就明白啥意思了)执行,适用重入经常出现的场景。代码如下:
private static int inTimer = 0;
/// &summary&
/// System.Timers.Timer的回调方法
/// &/summary&
/// &param name="sender"&&/param&
/// &param name="args"&&/param&
private static void TimersTimerHandler(object sender, EventArgs args)
int t = ++
if (inTimer == 0)
inTimer = 1;
Console.WriteLine(string.Format("线程{0}输出:{1},
输出时间:{2}", t, outPut.ToString(), DateTime.Now));
System.Threading.Thread.Sleep(2000);
Console.WriteLine(string.Format("线程{0}自增1后输出:{1},输出时间:{2}", t, outPut.ToString(), DateTime.Now));
inTimer = 0;
执行结果:
3、在多线程下给inTimer赋值不够安全,提供了一种轻量级的线程安全的给对象赋值的方法(感觉比较高上大,也是比较推荐的一种方法),执行结果与方法2一样,也是放弃执行。Interlocked.Exchange用法参考。
private static int inTimer = 0;
/// &summary&
/// System.Timers.Timer的回调方法
/// &/summary&
/// &param name="sender"&&/param&
/// &param name="args"&&/param&
private static void TimersTimerHandler(object sender, EventArgs args)
int t = ++
if (Interlocked.Exchange(ref inTimer, 1) == 0)
Console.WriteLine(string.Format("线程{0}输出:{1},
输出时间:{2}", t, outPut.ToString(), DateTime.Now));
System.Threading.Thread.Sleep(2000);
Console.WriteLine(string.Format("线程{0}自增1后输出:{1},输出时间:{2}", t, outPut.ToString(), DateTime.Now));
Interlocked.Exchange(ref inTimer, 0);
执行结果:
&&& 终于码完字了,真心不容易啊。写博客是个挺耗精力的事情,真心佩服那些大牛们笔耕不辍,致敬!在这里稍微总结一下,timer是一个使用挺简单的类,拿来即用,这里主要总结了使用timer时重入问题的解决,以前也没思考过这个问题,解决方案也挺简单,在这里列出了三种,主要参考在,不知道还有没有其他的方式。这里的解决方案同时也适用多线程的重入问题。时间不早了,洗洗睡了。
在这里列出文章中没有提及的参考,感谢各位前辈们智慧的结晶!
阅读(...) 评论()欢迎加入我们,一同切磋技术。 &
用户名: &&&
密 码: &
共有 5597 人关注过本帖
标题:timer如何停止,点运行后可再次启动周期事件
等 级:新手上路
帖 子:10
结帖率:100%
&&已结贴√
&&问题点数:10&&回复次数:4&&&
timer如何停止,点运行后可再次启动周期事件
在MenuStrip1控件中,在Form1窗体没有添加timer1控件
运行RunMenu_Click
&&&&&&&&private void RunMenu_Click(object sender, EventArgs e)
&&&&&&&&&&&&//到达时间的时候执行事件,周期为10秒;
&&&&&&&&&&&&System.Timers.Timer timer1 = new System.Timers.Timer(10 * 1000);
&&&&&&&&&&&&timer1.Elapsed += new System.Timers.ElapsedEventHandler(timer1_Tick);
&&&&&&&&&&&&timer1.AutoReset =&&//设置一直执行(true)
&&&&&&&&&&&&timer1.Enabled =&&& //是否执行System.Timers.Timer.Elapsed事件
&&&&&&&&&&&&RunMenu.Enabled =
&&&&&&&&&&&&StopMenu.Enabled =
&&&&&& private void timer1_Tick(object sender, EventArgs e)
&&&&&&&&&&&&//是连接sql,插入数据操作
停止StopMenu_Click,停止timer应该怎么实现呢
&&&&&&&&private void StopMenu_Click(object sender, EventArgs e)
&&&&&&&&&&&&??timer1 .Enabled = ??吗,timer1没有此参数。
&&&&&&&&&&&&RunMenu.Enabled =
&&&&&&&&&&&&StopMenu.Enabled =
请教,本人还是菜鸟
搜索更多相关主题的帖子:
来 自:北京
等 级:贵宾
威 望:27
帖 子:1432
专家分:6329
回家帮你解决``先回家喽 ~
[ 本帖最后由 zhoufeng1988 于
17:48 编辑 ]
来 自:北京
等 级:贵宾
威 望:27
帖 子:1432
专家分:6329
因为timer1是在RunMenu_Click方法域里,所以你在其他域里访问不到。
你可以尝试把timer1放到类域里,这样,StopMenu_Click方法里就可以访问了,要停止,调用timer1.Stop()就可以了。
等 级:小飞侠
帖 子:665
专家分:2832
以下是引用zhoufeng1988在 19:00:58的发言:
因为timer1是在RunMenu_Click方法域里,所以你在其他域里访问不到。
你可以尝试把timer1放到类域里,这样,StopMenu_Click方法里就可以访问了,要停止,调用timer1.Stop()就可以了。同意
等 级:蒙面侠
帖 子:1096
专家分:4969
&&&&&&&&&&&&System.Timers.Timer timer1 = new System.Timers.Timer(<font color=# * <font color=#0);
&&&&&&&&&&&&timer1.Elapsed += new System.Timers.ElapsedEventHandler(timer1_Tick);
放到form的load的事件里,或者更前面的构造函数里
[ 本帖最后由 jedypjd 于
10:53 编辑 ]
天涯无岁月,歧路有风尘,百年浑似醉,是非一片云
版权所有,并保留所有权利。
Powered by , Processed in 0.047977 second(s), 8 queries.
Copyright&, BCCN.NET, All Rights Reserved【转】使用C#的Timer控件来实现定时触发事件
【转】使用C#的Timer控件来实现定时触发事件
使用C#的Timer控件来实现定时触发事件,其主要参数如下:
Timer.Enabled 属性用于设置是否启用定时器
Timer.Interval 属性,事件的间隔,单位毫秒
Timer.Elapsed 事件,达到间隔时发生
System.Collections.G&&
System.L&&
System.T&&
System.T&&
ConsoleApplication1&&
class Program&&
static void Main(string[]
&&&&&&&&&&&
System.Timers.Timer aTimer = new
System.Timers.Timer();&&
&&&&&&&&&&&
aTimer.Elapsed += new
ElapsedEventHandler(OnTimedEvent);&&
&&&&&&&&&&&
// Set the Interval to 5
seconds.&&
&&&&&&&&&&&
aTimer.Interval =
&&&&&&&&&&&
aTimer.Enabled =
&&&&&&&&&&&
Console.WriteLine("Press \'q\' to quit the
sample.");&&
&&&&&&&&&&&
while (Console.Read() != 'q')
private static void OnTimedEvent(object source, ElapsedEventArgs
&&Console.WriteLine("Hello
World!");&&
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。使用C#的Timer控件来实现定时触发事件;C#Timer用法有哪些呢?我们在使用C#Tim;关于C#Timer类在C#里关于定时器类就有3个;C#Timer使用的方法1.定义在System.;C#Timer使用的方法2.定义在System.;C#Timer使用的方法3.定义在System.;下面我们来具体看看这3种C#Timer用法的解释;◆System.
使用C#的Timer控件来实现定时触发事件
C# Timer用法有哪些呢?我们在使用C# Timer时都会有自己的一些总结,那么这里向你介绍3种方法,希望对你了解和学习C# Timer使用的方法有所帮助。
关于C# Timer类
在C#里关于定时器类就有3个
C# Timer使用的方法1.定义在System.Windows.Forms里
C# Timer使用的方法2.定义在System.Threading.Timer类里
C# Timer使用的方法3.定义在System.Timers.Timer类里
下面我们来具体看看这3种C# Timer用法的解释:
◆System.Windows.Forms.Timer
应用于WinForm中的,它是通过Windows消息机制实现的,类似于VB或Delphi中的Timer控件,内部使用API
SetTimer实现的。它的主要缺点是计时不精确,而且必须有消息循环,Console
Application(控制台应用程序)无法使用。
◆System.Timers.Timer
和System.Threading.Timer非常类似,它们是通过.NET
Pool实现的,轻量,计时精确,对应用程序、消息没有特别的要求。
◆System.Timers.Timer还可以应用于WinForm,完全取代上面的Timer控件。它们的缺点是不支持直接的拖放,需要手工编码。
C# Timer用法实例
使用System.Timers.Timer类
System.Timers.Timer t =
new System.Timers.Timer(10000);
//实例化Timer类,设置间隔时间为10000毫秒;
t.Elapsed +=
new System.Timers.ElapsedEventHandler(theout);
//到达时间的时候执行事件;
t.AutoReset =
//设置是执行一次(false)还是一直执行(true);
t.Enabled =
//是否执行System.Timers.Timer.Elapsed事件;
public void theout(
object source,
System.Timers.ElapsedEventArgs e)
MessageBox.Show(&OK!&);
C# Timer用法的基本情况就向你介绍到这里,希望对你了解和学习C# Timer使用有所帮助。
三亿文库包含各类专业文献、应用写作文书、外语学习资料、中学教育、高等教育、各类资格考试、行业资料、73使用C#的Timer控件来实现定时触发事件等内容。 
 C#使用进度条ProgressBar和定时器Timer控件_计算机软件及应用_IT/计算机_专业资料...Enabled 属性来 控制是否激活定时器,使用 Tick 事件来实现定时器触发后实现的...  9. 2016年农大_C#程序设计_在线作业_1_教育学_...不能在表达式中或赋值语句中使用其 名称来调用它 13...6. Timer 控件的 Enabled 属性表示两个记时器事件...  C#程序设计_在线作业_1_司法考试_资格考试/认证_...不能在表达式中或赋值语句中使用其名称来调用它 C....Timer 控件的 Enabled 属性表示两个记时器事件之间的...  定时器控件只能响应Timer事件。 从几十个项目中任选其中一项或多项时可选用列表框或组合框控件来实现。...文件列表框的显示内容发生变化时,会触发Change事件。...  关于使用C#通过Timer控件实现自动播放图片的效果问题_计算机软件及应用_IT/计算机_专业资料。介绍了在C#中实现图片播放动能 关于使用 C#通过 Timer 控件实现自动播放...  【参考解答】 async 和 await 关键字是 C# 5.0 ...(3)利用 WPF 控件的调度器隐式创建和执行任务; (...(1)System.Timers.Timer 类; (2)System.Windows....  F 12.用 Interval 属性设置 Timer 控件 Tick 事件发生的时间间隔单位为秒。 T...21.在 C#Net 中,窗体父子关系通过“属性”窗口来创建。 22.使用 Directory 类...  Timer2 启动,每隔 0.01 秒,在触发定义的事件中给...Timer定时器控件 12页 免费
Timer 控件 暂无评价 ...使用C#的Timer控件来实现... 1页 免费 喜欢...  14、C#使用 ___BinoryReader___ 类和 __BinoryWriter___ 类对二进制文件进行...数组 25. 计时器 Timer 控件的 Interval 属性可以设置定时发生的事件的间隔,...

我要回帖

更多关于 python 定时器 timer 的文章

 

随机推荐