解读 --- System.Windows.Forms.Timer是前台线程吗?

这篇具有很好参考价值的文章主要介绍了解读 --- System.Windows.Forms.Timer是前台线程吗?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

引言

今天同事问了我一个问题,System.Windows.Forms.Timer是前台线程还是后台线程,我当时想的是它是跟着UI线程一起结束的,应该是前台线程吧?

我确实没有仔细研究过他们的异同,所以带着这个疑问探究一下System.Windows.Forms.Timer

System.Windows.Forms.Timer

机制

System.Windows.Forms.TimerWindows Forms 中的一个定时器控件,它的工作原理基于 Windows 消息循环机制。

这个Windows消息循环机制说简单一点就是它有一个消息队列,一个while(true) 循环结构,一个窗口消息处理函数,消息队列保存了在应用程序或系统中发生的各种事件和消息,如鼠标点击、键盘输入、窗口重绘等。循环结构消息队列中不断取出消息。然后通过窗口消息处理函数分发给相应的窗口过程进行处理。

System.Windows.Forms.Timer 的事件触发机制如下:

  • Timer 控件利用 Windows 的消息机制来触发 Tick 事件。在定时器启动后,它会在每个 Interval 时间间隔后,将一个 WM_TIMER 消息放入应用程序的消息队列。
  • WM_TIMER 是一个定时器消息,它是由 Windows 消息循环派发的。
  • 当应用程序处理消息循环时,当收到 WM_TIMER 消息,就会触发 Timer 的 Tick 事件。

源码解析

来通过源码看一下它的触发机制(这里节选了部分重要函数),它的源码还是比较简单的,仅有300多行。我们先来看一下 System.Windows.Forms.Timer 的调用,一般是这样使用:

using System.Windows.Forms;

// 创建一个 Timer 实例
Timer timer = new Timer();
// 设置触发间隔时间(以毫秒为单位)
timer.Interval = 1000; // 1000 毫秒 = 1 秒
// 绑定 Tick 事件处理程序
timer.Tick += Timer_Tick;
// 启动 Timer
timer.Start();

// Tick 事件处理程序
private void Timer_Tick(object sender, EventArgs e)
{
    // 定时触发的操作
}

我们就按照上面的步骤来剖析一下源码:

第一步:创建实例

这一步并无特别,无参构造默认创建的实例默认 Interval 值为100。含参构造创建时会将该实例添加到参数容器中。

第二步:注册Tick

System.Windows.Forms.Timer 声明了一个 onTimer 委托,注册 Tick 是将注册的方法赋值给 onTimer 委托。

第三步:启动Timer

可以看到Timer的 Start()Stop(),实际都是给 Enabled 赋值,所以我们可以着重看一下 Enabled 属性的 Setter 方法。

第四步:TimerNativeWindow 启动

可以看到System.Windows.Forms.Timer 持有一个 TimerNativeWindow 类型的私有变量,是由这个私有变量启动的Timer.

第五步:TimerNativeWindow 实现

上一步中,可以看到当 Enable 置为 true 时,一个 TimerNativeWindow 类型的私有变量调用了 StartTimer(interval) 方法,那么来看一下这个 TimerNativeWindow 的实现。

如下图,可以看到当 TimerNativeWindow 调用 StartTimer()时,调用了 SafeNativeMethods.SetTimer 方法,传入了当前Timer的窗口句柄,还有加1后的 _timerID ,以及间隔 Interval

该方法的作用就是向Windows消息循环机制的消息队列中插入一条Timer消息。

上图中,我除了框出了StartTimer()方法,还框出了 WndProc(ref Message m) 方法。这个方法就很重要了。这个就是上面所说的 Windows 消息循环机制中的窗口消息处理函数

WndProc(ref Message m) 方法就是一个用于处理窗口消息的回调函数。当窗口接收到不同类型的消息时(例如鼠标事件、键盘事件、绘图事件等,包括Timer的触发事件),窗口过程会被调用来处理这些消息并作出相应的响应。

大家可能会很好奇该方法中的两个判断条件是什么意思?275 和 16 分别代表什么?

实际上这个是Windows消息标识符的十进制值。实际上他们是在名为 WinUser.h 的c++ 头文件中定义的。它随SDK一起安装到电脑上,可以通过Everything 直接找到它。

而我们要找的消息 275 和 16 就是下面这两个

  • WM_TIMER :其16进制为0x0113,转化为10进制则为275。
  • WM_CLOSE :其16进制为0x0010,转化为10进制则为16。

这样就可以理解WndProc(ref Message m) 方法的作用了,就是获取到 WM_TIMER 消息时,触发 System.Windows.Forms.TimerOnTick 方法。而获取到 WM_CLOSE 消息时,则调用 StopTimer(),结束定时器。

结论

通过上面的机制和源码分析,可以得出结论,System.Windows.Forms.Timer 并不是线程,而是依赖于UIx线程,依赖于Windows消息循环机制而实现的定时器。

所以回到开篇的问题,这个问题本身就有问题,System.Windows.Forms.Timer 并不是线程。文章来源地址https://www.toymoban.com/news/detail-623643.html

到了这里,关于解读 --- System.Windows.Forms.Timer是前台线程吗?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C# 计时器(Timer )WPF窗体出现“System.InvalidOperationException:“调用线程必须为 STA,因为许多 UI 组件都需要。””

    大家在WPF窗体使用计时器(Timer)的时候可能会出现一个这样的错误“System.InvalidOperationException:“调用线程必须为 STA,因为许多 UI 组件都需要。””,这个错误一般都是线程的问题,我们可以使用另一种计时器(DispatcherTimer)来避免发生这种问题。 以上就是解决Timer计时器出

    2024年02月04日
    浏览(41)
  • 没有注册类 (异常来自 HRESULT:0x80040154 (REGDB_E_CLASSNOTREG)) 在 System.Windows.Forms.UnsafeNativeMethods.C

    今天在有些客户的电脑上安装程序时日志提示了以下错误: 2023-03-10 08:34:42.659 +08:00 [INF] 没有注册类 (异常来自 HRESULT:0x80040154 (REGDB_E_CLASSNOTREG)) 在 System.Windows.Forms.UnsafeNativeMethods.CoCreateInstance(Guid clsid, Object punkOuter, Int32 context, Guid iid) 在 System.Windows.Forms.AxHost.CreateWithLicense(Strin

    2024年02月02日
    浏览(26)
  • 多线程(初阶八:计时器Timer)

    目录 一、标准库中的计时器 1、计时器的概念 2、计时器的简单介绍 二、模拟实现一个计时器 1、思路 (1)计数器中要存放任务的数据结构 (2)存放优先级队列中的类型:自定义任务类MyTimerTask (3)计数器类MyTimer MyTimer类: MyTimerTask任务类: 2、分析计时器的线程安全问题

    2024年02月04日
    浏览(29)
  • 【Java|多线程与高并发】定时器(Timer)详解

    在Java中,定时器 Timer 类是用于执行定时任务的工具类。它允许你安排一个任务在未来的某个时间点执行,或者以固定的时间间隔重复执行。 在服务器开发中,客户端向服务器发送请求,然后等待服务器响应. 但服务器什么时候返回响应,并不确定. 但也不能让客户端一直等下去

    2024年02月07日
    浏览(35)
  • Java 多线程6——计时器Timer的使用 + 详细代码模拟实现 + 代码优化

    本人是一个刚刚上路的IT新兵,菜鸟!分享一点自己的见解,如果有错误的地方欢迎各位大佬莅临指导,如果这篇文章可以帮助到你,劳请大家点赞转发支持一下! 本篇文章为大家带来的仍然是多线程编程,计时器是许多场景都会应用到的一个非常方便快捷实用的类。 🦉定时器,顾

    2024年02月04日
    浏览(37)
  • TX Text Control .NET for Windows Forms 32 Crk

    WINDOWS UI TX Text Control is a royalty-free, fully programmable rich edit control that offers developers a broad range of word processing features in a reusable component designed for Visual Studio. It provides comprehensive text formatting, powerful mail merge features and all word processing key concepts such as table support, images, headers and footers

    2024年02月07日
    浏览(33)
  • TX Text Control 31.SP3 for Windows Forms Crack

    视窗用户界面 TX 文本控件是一种完全可编程的丰富编辑控件,可在专为 Visual Studio 设计的可重用组件中为开发人员提供广泛的文字处理功能。它提供全面的文本格式,强大的邮件合并功能和所有文字处理关键概念,如表格支持,图像,页眉和页脚以及页面部分。 全面的文本

    2024年02月12日
    浏览(36)
  • unity多线程Burst+Job System

    Unity自己本身UnityEngine所使用的API是不能被多线程调用的,它没有向用户开放线程接口,所以Unity是不能使用多线程的,但是C#中可以使用多线程,Unity使用C#进行脚本编辑,故而Unity也可以通过C#来调用多线程。 JobSystem 是Unity Dots(多线程运行框架)的核心组件之一,也可以把它拿

    2024年02月04日
    浏览(28)
  • C# 解决 System.InvalidOperationException:“线程间操作无效: 从不是创建控件“...”的线程访问它。”

    方法1(不推荐):禁用跨线程检查 使用 Control.CheckForIllegalCrossThreadCalls = false; 例如: 方法2:使用委托 使用 Control 基类的 Invoke 或 BeginInvoke 方法,来执行禁止跨线程的代码。 例如: 或: 使用参数进行传递: 不使用 lambda 表达式的写法: 使用 BeginInvoke 方法的情形,与使用

    2024年02月12日
    浏览(32)
  • 论文解读--Wideband 120 GHz to 140 GHz MIMO Radar:System Design and Imaging Results

            本文提出了一种工作频率在120 GHz ~ 140 GHz之间的宽带FMCW MIMO雷达传感器。该传感器基于SiGe技术制造的雷达芯片组,并使用MIMO方法来提高角度分辨率。MIMO操作通 过发射机的时域复用实现 。该雷达能够通过使用FFT处理和延迟和波束形成器产生2D图像。本文给出了雷达

    2024年01月25日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包