• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >ASP.NET > .NET Framework中定时器timer的单线程与多线程使用讲解

.NET Framework中定时器timer的单线程与多线程使用讲解

作者:winnow 字体:[增加 减小] 来源:互联网 时间:2017-05-11

winnow通过本文主要向大家介绍了net framework 4.0,net framework,net framework 3.5,net framework 2.0,.net framework 4.5等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

如果你需要使用规律的时间间隔重复执行一些方法,最简单的方式是使用定时器(timer)。与下边的例子相比,定时器可以便捷、高效地使用内存和资源:

new Thread (delegate() {
             while (enabled)
             {
              DoSomeAction();
              Thread.Sleep (TimeSpan.FromHours (24));
             }
            }).Start();
</div>

这不仅仅会永久占用一个线程,而且如果没有额外的代码,DoSomeAction每天都会发生在更晚的时间。定时器解决了这些问题。

.NET Framework 提供了 4 种定时器。下边两个类是通用的多线程定时器:

(1)System.Threading.Timer
(2)System.Timers.Timer
另外两个是专用的单线程定时器:

(3)System.Windows.Forms.Timer (Windows Forms 的定时器)
(4)System.Windows.Threading.DispatcherTimer (WPF 的定时器)
多线程定时器更加强大、精确并且更加灵活,而单线程定时器对于一些简单的更新 Windows Forms 和 WPF 控件的任务来说是安全的,并且更加便捷。

1.多线程定时器Permalink

System.Threading.Timer是最简单的多线程定时器:它仅仅有一个构造方法和两个普通方法(取悦于极简主义者,还有本书作者!)。在接下来的例子中,一个定时器在 5 秒钟之后调用Tick方法来打印 “ tick… “,之后每秒打印一次直到用户按下回车键:

using System;
using System.Threading;

class Program
{
 static void Main()
 {
  // 首次间隔 5000ms,之后间隔 1000ms
  Timer tmr = new Timer (Tick, "tick...", 5000, 1000);
  Console.ReadLine();
  tmr.Dispose();     // 停止定时器并执行清理工作
 }

 static void Tick (object data)
 {
  // 这里运行在一个线程池线程上
  Console.WriteLine (data);     // 打印 "tick..."
 }
}

</div>

之后可以通过调用Change方法来改变定时器的时间间隔。如果你希望定时器只触发一次,可以指定Timeout.Infinite作为构造方法的最后一个参数。

.NET Framework 在System.Timers命名空间下提供了另一个名字相同的定时器类。它只是封装了 System.Threading.Timer,并在使用完全相同的底层引擎的前提下提供额外的便利。下面是增加功能的简介:

(1)实现了Component,允许用于 Visual Studio 的设计器中。
(2)Interval属性代替了Change方法。
(3)Elapsed事件代替了回调委托。
(4)Enabled属性用于开始或停止定时器(默认值是false)。
(5)Start和Stop方法,避免对Enabled属性感到困惑。
(6)AutoReset标识来指定是否为可重复的事件(默认为true)。
SynchronizingObject属性提供Invoke和BeginInvoke方法,用于在 WPF 和 Windows Forms 控件上安全调用方法。
这有个例子:

using System;
using System.Timers;  // 命名空间是 Timers 而不是 Threading

class SystemTimer
{
 static void Main()
 {
  Timer tmr = new Timer();    // 无需任何参数
  tmr.Interval = 500;
  tmr.Elapsed += tmr_Elapsed;  // 使用事件代替委托
  tmr.Start();          // 开启定时器
  Console.ReadLine();
  tmr.Stop();          // 停止定时器
  Console.ReadLine();
  tmr.Start();          // 重启定时器
  Console.ReadLine();
  tmr.Dispose();         // 永久停止定时器
 }

 static void tmr_Elapsed (object sender, EventArgs e)
 {
  Console.WriteLine ("Tick");
 }
}

</div>

多线程定时器使用线程池来允许少量线程服务多个定时器。这意味着,回调方法或Elapsed事件每次可能会在不同的线程上触发。此外,不论之前的Elapsed是否完成执行,Elapsed总是几乎按时触发。因此,回调方法或事件处理器必须是线程安全的。

多线程定时器的精度依赖于操作系统,通常是在 10-20 ms 的区间。如果需要更高的精度,你可以使用本地互操作(native interop)来调用 Windows 多媒体定时器,可以让精度提升到 1 ms。它定义在 winmm.dll 中,首先调用timeBeginPeriod来通知操作系统你需要更高的定时器精度,然后调用timeSetEvent来启动多媒体定时器。当使用完成后,调用timeKillEvent停止定时器,最后调用timeEndPeriod通知操作系统你不在需要更高的定时器精度了。可以通过搜索关键字 dllimport winmm.dll timesetevent 在网上找到完整的例子。

2.单线程定时器Permalink

.NET Framework 提供了两个定时器,为消除WPF 和 Windows Forms 应用程序的线程安全问题而设计:

System.Windows.Threading.DispatcherTimer(WPF)
System.Windows.Forms.Timer(Windows Forms)
单线程定时器不是被设计成能在其特定的环境外工作的。例如,如果在 Windows 系统服务应用程序中使用 Windows Forms 定时器,Timer事件不会触发!

它们暴露的成员都像System.Timers.Timer一样(Interval、Tick、Start和Stop),并且用法也类似。但是不同之处在于其内部是如何工作的。它们不是使用线程池来产生定时器事件,WPF 和 Windows Forms 定时器依赖于 UI 模型的底层消息循环机制(message pumping mechanism)。意味着Tick事件总是在创建该定时器的那个线程触发,在通常的程序中,它也就是管理所有 UI 元素和控件的那个线程。这有很多好处:

单线程计时器比较安全,对于更新 Windows Forms controls或者WPF这种简单任务来说更方便。在WPF或Windows Forms中安全的调用方法的SynchronizingObject对象。
单线程计时器是被设计成属于他们执行环境的计时器,如果你在一个Windows服务应用程序中使用Windows Forms的Timer,timer 事件并不会被触发,只有在对应的环境下才会被触发。
像System.Timers.Timer一样,他们也提供了相同的成员(Interval,Tick,Start,Stop),但是他们内部的工作原理不同,WPF和Windows Forms的计时器使用消息循环机制来取代线程池产生消息的机制。

你可以不必考虑线程安全。
新的Tick在之前的Tick完成执行前不会触发。
你可以直接在Tick时间事件的处理代码中更新 UI 控件,而不需要调用Control.Invoke或Dispatcher.Invoke。
这听起来好的难以置信,直到你意识到使用这些定时器的程序并不是真正的多线程,不会有并行执行。一个线程服务于所有定时器,并且还处理 UI 事件。这带来了单线程定时器的缺点:

除非Tick事件处理器执行的很快,否则 UI 会失去响应。
这使得 WPF 和 Windows Forms 定时器仅适用于小任务,通常就是那些更新 UI 外观的任务(例如,显示时钟或倒计时)。否则,你就需要多线程定时器。

在精度方面,单线程定时器与多线程定时器类似(几十毫秒),但是通常精度更低,因为它们会被其它 UI 请求(或其它定时器事件)推迟。

单线程计时器基于Windows消息循环,应用程序会同步的处理计时器的消息。会发现UI界面相应速度比较慢。解决这个问题的方法是使用多线程计时器。
单线程计时器的缺点:除非Tick事件的处理代码执行的非常快,否则UI界面会变得响应很慢。所以 WPF和Windows Forms的计时器都非常适合小任务,尤其是界面更新的任务。例如时钟和计数显示。否则,你需要一个多线程计时器


</div>
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • Visual studio 2017如何发布dotnet core到docker
  • .NET中用ICSharpCode.TextEditor自定义代码折叠与高亮
  • .NET framework 4.0 安装失败回滚问题
  • 详解免费开源的DotNet任务调度组件Quartz.NET(.NET组件介绍之五)
  • 安装.NET Framework进度条卡住不动的解决方案(推荐)
  • .NET Framework中定时器timer的单线程与多线程使用讲解
  • .net等比缩放生成缩略图的方法
  • 解决.net framework 4.0环境下遇到版本不同编译不通过的方法详解
  • 关于.NET Framework中的设计模式--应用策略模式为List排序
  • .net框架(framework)版本不匹配的解决方法

相关文章

  • 2017-05-11asp.net 生成静态时的过滤viewstate的实现方法
  • 2017-05-11asp.net使用Socket.Send发送信息及Socket.SendFile传输文件的方法
  • 2017-05-11asp.net安全、实用、简单的大容量存储过程分页第1/2页
  • 2017-05-11Asp.net mvc 权限过滤和单点登录(禁止重复登录)
  • 2017-05-11Asp.net 页面调用javascript变量的值
  • 2017-05-11DataView.RowFilter的使用(包括in,like等SQL中的操作符)
  • 2017-05-11三步将Asp.Net页面输出到EXCEL里
  • 2017-05-11ASP.net中获取客户端参数操作系统信息
  • 2017-05-11弹出窗口,点击确定在删除数据的实现方法
  • 2017-05-11使用UserControl做网站导航条的思路 分析

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • .NET桥接模式讲解
    • .NET原型模式讲解
    • ASP.NET中的C#基础知识
    • asp.net 页面转向 Response.Redirect, Server.Transfer, Server.Execute的区别
    • asp.net web页面自定义分页控件使用详解
    • asp.NET连接数的设置方法
    • 未处理的事件"PageIndexChanging" 之解决方案
    • ABP框架的基础配置及依赖注入讲解
    • 使用aspnet_regiis.exe重新注册.NET Framework
    • asp.net 实现下拉框只读功能

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有