Timer in C#

                                    服务器计时器、Windows 计时器和线程计时器
        在 Visual Studio .NET 和 .NET Framework 中有三种计时器控件:基于服务器的计时器,位于“工具箱”的“组件”选项卡上;基于 Windows 的标准计时器,位于“工具箱”的“Windows 窗体”选项卡上,以及仅可在编程时使用的线程计时器。基于 Windows 的计时器从 Visual Basic 的 1.0 版起就存在于该产品中并且基本上保持不变。该计时器已经为在 Windows 窗体应用程序中使用而进行了优化。基于服务器的计时器是传统的计时器为了在服务器环境上运行而优化后的更新版本。线程计时器是一种简单的、轻量级计时器,使用回调方法而不是事件,并由线程池线程提供。

         在 Win32 体系结构中有两种类型的线程:UI 线程和辅助线程。UI 线程绝大多数时间处于空闲状态,等待消息循环中的消息到来。一旦接收到消息,它们就进行处理并等待下一个消息到来。另外,辅助线程用来执行后台处理而且不使用消息循环。Windows 计时器和基于服务器的计时器在运行时都使用 Interval 属性。线程计时器的时间间隔在 Timer 构造函数中设置。计时器的设计目的各不相同,它们的线程处理明确地指出了这一点:

        Windows 计时器是为单线程环境设计的,其中,UI 线程用于执行处理。Windows 计时器的精度限定为 55 毫秒。这些传统计时器要求用户代码有一个可用的 UI 消息泵,而且总是在同一个线程中操作,或者将调用封送到另一个线程。对于 COM 组件来说,这样会降低性能。
基于服务器的计时器是为在多线程环境下与辅助线程一起使用而设计的。由于它们使用不同的体系结构,因此基于服务器的计时器可能比 Windows 计时器精确得多。服务器计时器可以在线程之间移动来处理引发的事件。
        对消息不在线程上发送的方案中,线程计时器是非常有用的。例如,基于 Windows 的计时器依赖于操作系统计时器的支持,如果不在线程上发送消息,与计时器相关的事件将不会发生。在这种情况下,线程计时器就非常有用。
        Windows 计时器位于 System.Windows.Forms 命名空间中,服务器计时器位于 System.Timers 命名空间中,而线程计时器位于 System.Threading 命名空间中。

### 使用 Timer 组件的示例 在 C# WinForms 中,`System.Windows.Forms.Timer` 是一种常用的计时器控件,用于定期执行某些操作。以下是关于如何配置和使用 `Timer` 的详细说明。 #### 创建并设置 Timer 控件 可以通过设计界面拖放或者通过代码创建 `Timer` 对象。以下是一个完整的代码示例: ```csharp using System; using System.Timers; // 如果需要更高精度可以引入此命名空间 using System.Windows.Forms; public class TimerExample : Form { private Label label; private Timer timer; public TimerExample() { label = new Label(); label.Text = "0"; label.AutoSize = true; label.Location = new System.Drawing.Point(10, 10); this.Controls.Add(label); // 初始化 Timer timer = new Timer(); timer.Interval = 1000; // 设置间隔时间为 1 秒 timer.Tick += OnTimedEvent; // 订阅 Tick 事件 timer.Start(); // 启动定时器 } private void OnTimedEvent(object sender, EventArgs e) { int count = int.Parse(label.Text); // 获取当前标签显示的时间 count++; // 增加时间 label.Text = count.ToString(); // 更新标签文字 } } // 主程序入口 static class Program { [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new TimerExample()); } } ``` 上述代码展示了如何初始化一个简单的计时器,并将其绑定到窗体上的一个 `Label` 上。每次触发 `Tick` 事件时,都会更新该标签的内容[^4]。 #### 关于异步资源请求处理 如果涉及到更复杂的场景,比如加载外部资源或网络数据,则可能需要用到回调函数来控制流程。例如,在 CEFSharp 库中,可以在资源请求之前调用特定方法以实现异步处理[^2]: ```csharp bool OnBeforeResourceLoad(IWebBrowser browser, IRequest request, IResponse response, ref bool cancel) { var callback = request.RequestCallback; if (callback != null && ShouldProcessAsynchronously(request)) { cancel = true; // 阻止默认行为 return CefReturnValue.ContinueAsync; // 返回继续状态 } return CefReturnValue.Continue; } ``` 虽然这段代码主要用于浏览器插件开发环境下的资源拦截功能,但它也体现了如何利用回调机制完成延迟任务管理[^5]。 #### 屏幕保护程序中的双缓冲技术应用 对于多显示器系统的屏幕保护应用程序来说,采用双缓冲绘图方式能够有效减少闪烁现象的发生。下面是从另一个角度出发的一个例子——基于 C# 实现带有多监视器支持以及平滑动画效果的自定义屏幕保护方案[^3]: ```csharp protected override CreateParams CreateParams { get { const int WS_EX_COMPOSITED = 0x02000000; CreateParams cp = base.CreateParams; cp.ExStyle |= WS_EX_COMPOSITED; // 开启硬件加速渲染模式 return cp; } } private void AnimateScreensaver(Graphics g) { foreach (Screen screen in Screen.AllScreens) { Rectangle bounds = screen.Bounds; using (Bitmap bufferImage = new Bitmap(bounds.Width, bounds.Height)) // 构建离屏缓存图像对象 { Graphics offscreenGraphics = Graphics.FromImage(bufferImage); DrawContent(offscreenGraphics); // 调用实际绘制逻辑 lock (this) { g.DrawImageUnscaledAndClipped(bufferImage, bounds); } // 将最终结果同步刷新至目标区域 } } } ``` 以上片段重点在于通过构建临时位图作为中间载体来进行预渲染工作,从而避免频繁重画引起视觉干扰问题。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值