C#学习笔记
一、事件派发器
在C#中,事件派发器通常是指事件委托和事件处理程序的组合,用于实现一种观察者设计模式。它允许对象在状态发生变化时通知其他对象,从而实现对象之间的解耦。
事件派发器的基本组成部分:
事件委托(Event Delegate): 事件委托是一种特殊的委托,用于封装可以被调用的方法。它定义了事件的签名,即指定了事件处理程序方法的参数和返回类型。通常,事件委托声明在事件派发器类的外部,并且使用 delegate 关键字来定义。例如:
public delegate void MyEventHandler(object sender, EventArgs e);
事件(Event): 事件是事件委托的实例,它提供了一种触发事件和订阅事件的机制。在事件派发器类中声明事件,其他类可以通过订阅该事件来注册事件处理程序。事件通常使用event关键字声明。例如:
public event MyEventHandler MyEvent;
事件处理程序(Event Handler): 事件处理程序是一个方法,用于响应事件的发生。它必须具有与事件委托相同的签名。当事件被触发时,与该事件关联的事件处理程序将被调用。例如:
public void MyEventHandlerMethod(object sender, EventArgs e)
{
//其他逻辑
}
事件触发器(Event Trigger): 事件触发器是事件派发器类中的方法,用于触发事件。当某些条件满足时,调用事件触发器方法将会触发事件,从而执行与事件关联的事件处理程序。通常,事件触发器方法使用protected 或protected virtual修饰,以便子类可以重写它。例如:
protected virtual void OnMyEvent(EventArgs e)
{
MyEvent?.Invoke(this, e);
}
Invoke 方法用于触发事件,它的第一个参数是事件的发布者(通常是 this ,表示当前对象),第二个参数是一个包含事件信息的EventArgs 对象e。
示例:假设我们有一个游戏中的角色类 Player,我们想要在角色受到伤害时触发一个事件来通知其他对象,比如显示受伤效果或更新 UI。
首先,定义一个事件委托和一个事件:
using System;
public class Player
{
// 事件委托
public delegate void DamageEventHandler(int damageAmount);
// 事件
public event DamageEventHandler Damaged;
// 触发受伤事件的方法
public void TakeDamage(int damageAmount)
{
//触发受伤事件
OnDamaged(damageAmount);
}
//触发事件的方法
protected virtual void OnDamaged(int damageAmount)
{
//检查事件是否有订阅者,如果有则调用事件处理程序
Damaged?.Invoke(damageAmount);
}
}
在这个例子中,DamageEventHandler 是一个事件委托,定义了一个受伤事件的签名,即参数为受到的伤害值。Damaged 是一个事件,它使用了 DamageEventHandler 委托。
再创建一个订阅事件的类 DamageEffect,用于处理角色受到伤害时的效果:
using System;
public class DamageEffect
{
// 受伤事件处理程序
public void OnPlayerDamaged(int damageAmount)
{
Console.WriteLine("角色受到伤害的效果");
}
}
最后,创建一个 Main 方法来模拟游戏的运行过程,并进行事件的订阅和触发:
class Program
{
static void Main(string[] args)
{
Player player = new Player();
DamageEffect damageEffect = new DamageEffect();
player.Damaged += damageEffect.OnPlayerDamaged;// 订阅事件
player.TakeDamage(20); // 触发事件
}
}
在Main方法中,创建了 Player 和 DamageEffect 的实例,并将 DamageEffect 的QnPlayerDamaged 方法订阅到了 Player 的 Damaged 事件上。
然后,通过调用 TakeDamage 方法来模拟角色受到了20点伤害,这将触发Damaged事件,最终调用 QnPlayerDamaged 方法,显示了受伤效果并输出了相应的信息。这是因为通常在 C# 中,事件可以被订阅,而当事件被触发时,所有订阅了该事件的方法都会被调用。
二、定时器
C#中的四种常用的定时器:
1. System.Windows.Forms.Timer
System.Windows.Forms.Timer是Windows窗体应用程序中常用的定时器。它是基于消息循环的,工作在UI线程上,并且适用于Windows窗体应用程序的GUI更新。
示例:
using System;
using System.Windows.Forms;
public class MyForm : Form
{
private Timer timer;
public MyForm()
{
timer = new Timer();
timer.Interval = 1000; // 每秒触发一次
timer.Tick += Timer_Tick; // 订阅 Tick 事件
timer.Start(); // 启动定时器
}
private void Timer_Tick(object sender, EventArgs e)
{
Console.WriteLine("计时器触发时间: " + DateTime.Now);
}
}
2. System.Threading.Timer
System.Threading.Timer是在.NET中常用的多线程环境下的定时器。它是基于线程池的,可以在一个独立的线程中触发回调函数。
示例:
using System;
using System.Threading;
public class MyTimer
{
private Timer timer;
public MyTimer()
{
timer = new Timer(TimerCallback, null, 0, 1000); // 每秒触发一次
}
private void TimerCallback(object state)
{
Console.WriteLine("计时器触发时间: " + DateTime.Now);
}
}
3. System.Timers.Timer
System.Timers.Timer是在.NET中常用的定时器,类似于`System.Threading.Timer,但是它更适合于在单线程环境下使用,例如Windows服务等。
示例:
using System;
using System.Timers;
public class MyTimer
{
private Timer timer;
public MyTimer()
{
timer = new Timer(1000); // 每秒触发一次
timer.Elapsed += Timer_Elapsed; // 订阅 Elapsed 事件
timer.Start(); // 启动定时器
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
Console.WriteLine("计时器触发时间: " + DateTime.Now);
}
}
4. System.Windows.Threading.DispatcherTimer
System.Windows.Threading.DispatcherTimer是用于WPF应用程序的定时器,它与System.Windows.Forms.Timer类似,但是工作在WPF 的UI线程上。
示例:
using System;
using System.Windows.Threading;
public class MyViewModel
{
private DispatcherTimer timer;
public MyViewModel()
{
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(1); // 每秒触发一次
timer.Tick += Timer_Tick; // 订阅 Tick 事件
timer.Start(); // 启动定时器
}
private void Timer_Tick(object sender, EventArgs e)
{
Console.WriteLine("计时器触发时间: " + DateTime.Now);
}
}
相关文章:
C#学习笔记
一、事件派发器 在C#中,事件派发器通常是指事件委托和事件处理程序的组合,用于实现一种观察者设计模式。它允许对象在状态发生变化时通知其他对象,从而实现对象之间的解耦。 事件派发器的基本组成部分: 事件委托(Ev…...
【A-006】基于SSH的新闻发布系统(含论文)
【A-006】基于SSH的新闻发布系统(含论文) 开发环境: Jdk7(8)Tomcat7(8)MySQLIntelliJ IDEA(Eclipse) 数据库: MySQL 技术: SpringStruts2HiberanteJSPJquery 适用于: 课程设计,毕业设计&…...
c语言-static
static作用:修饰变量和函数 修饰局部变量-静态局部变量 static未修饰局部变量 #include <stdio.h>void print() {int a 0;a;printf("%d ", a); }int main() {int i 0;for (i 0; i < 10; i){print();}return 0; }运行结果 static修饰局部变…...
zuul的性能调优
文章目录 zuul的性能调优Zuul参数剖析semaphore(信号量)ribbonhystrix高并发下常见Zuul异常熔断 zuul 1.x 与2.x的区别与总结 zuul的性能调优 在项目实践中,使用jemeter多线程并发访问微服务中的接口时候,在Zuul层出现异常、超时等,从而导致整…...
C++中的动态内存管理
1.C中动态内存管理 C语言内存管理方式在C中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因此C又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。 1.1 new/delete操作内置类型 c语言和c的动态内存…...
es6的核心语法
在学习低代码时,经常有粉丝会问,低代码需要什么基础,es6就是基础中的一项。我们本篇是做一个扫盲,可以让你对基础有一个概要性的了解,具体的每个知识点可以深入进行了解,再结合官方模板就会有一个不错的掌握…...
Unity | 射线检测及EventSystem总结
目录 一、知识概述 1.Input.mousePosition 2.Camera.ScreenToWorldPoint 3.Camera.ScreenPointToRay 4.Physics2D.Raycast 二、射线相关 1.3D(包括UI)、射线与ScreenPointToRay 2.3D(包括UI)、射线与ScreenToWorldPoint …...
职业经验 2024 年测试求职手册
原贴地址: 2024 年测试求职手册 TesterHome 经历年前年后差不多 2 个月左右时候的求职,是时候总结复盘一下了,本打算在自己有着落再复盘,但是一想那时候似乎价值就没现在去做显得有意义一些,这篇帖子更多的是让大家看下有没有心…...
Spring Boot与Redis深度整合:实战指南
Spring Boot 整合 Redis 相当简单,它利用了 Spring Data Redis 项目,使得我们可以在 Spring Boot 应用中轻松地操作 Redis。以下是如何整合 Redis 到 Spring Boot 应用的基本步骤: 1. 添加依赖 首先,在你的 pom.xml 文件中添加 …...
微服务(基础篇-006-Docker安装-CentOS7)
目录 05-初识Docker-Docker的安装_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1LQ4y127n4?p46&spm_id_frompageDriver&vd_source60a35a11f813c6dff0b76089e5e138cc 0.安装Docker 1.CentOS安装Docker 1.1.卸载(可选) 1.2.安装dock…...
前端-css-01
1.CSS 长度单位和颜色设置 1.1CSS 中的长度单位 px 像素 em 字体大小的倍数(字体默认是16px) % 百分比 1.2CSS 中的颜色设置方式 1.2.1使用颜色名表示颜色 red、orange、yellow、green、cyan、blue、purple、pink、deeppink、skyblue、greenyellow .…...
Java学习36-Java 多线程安全:懒汉式和饿汉式
JAVA种有两种保证线程安全的方式,分别叫懒汉式Lazy Initialization和饿汉式Eager Initialization,以下是他们的区别: 线程安全性: 懒汉式本身是非线程安全的,因为多个线程可能同时检查实例是否为null,并尝…...
sql常用之CASE WHEN THEN
sql常用之CASE WHEN THEN SQL中的 CASE 类似编程语言里的 if-then-else 语句,用做逻辑判断。可以用于SELECT语句中,也可以用在WHERE,GROUP BY 和 ORDER BY 子句;可以单独使用,也可以和聚合函数结合使用。 语法&#…...
【PduR路由】IPduM模块详细介绍
目录 1.IpduM功能简介 2.IpduM模块依赖的其他模块 2.1RTE (BSW Scheduler) 2.2PDU Router 2.3COM 3.IpduM功能详解 3.1 功能概述 3.2 I-PDU多路复用I-PDU Multiplexing 3.2.1 Definitions and Layout 3.2.2通用功能描述 General 3.2.3模块初始化 Initialization 3.…...
【MySQL】6.MySQL主从复制和读写分离
主从复制 主从复制与读写分离 通常数据库的读/写都在同一个数据库服务器中进行; 但这样在安全性、高可用性和高并发等各个方面无法满足生产环境的实际需求; 因此,通过主从复制的方式同步数据,再通过读写分离提升数据库的并发负载…...
Lucene及概念介绍
Lucene及概念介绍 基础概念倒排索引索引合并分析查询语句的构成 基础概念 Document:我们一次查询或更新的载体,对比于实体类 Field:字段,是key-value格式的数据,对比实体类的字段 Item:一个单词࿰…...
密码算法概论
基本概念 什么是密码学? 简单来说,密码学就是研究编制密码和破译密码的技术科学 例题: 密码学的三个阶段 古代到1949年:具有艺术性的科学1949到1975年:IBM制定了加密标准DES1976至今:1976年开创了公钥密…...
实时数仓之实时数仓架构(Hudi)
目前比较流行的实时数仓架构有两类,其中一类是以FlinkDoris为核心的实时数仓架构方案;另一类是以湖仓一体架构为核心的实时数仓架构方案。本文针对FlinkHudi湖仓一体架构进行介绍,这套架构的特点是可以基于一套数据完全实现Lambda架构。实时数…...
2022-04-15_for循环等_作业
for循环 编写程序数一下 1到 100 的所有整数中出现多少个数字9计算1/1-1/21/3-1/41/5 …… 1/99 - 1/100 的值,打印出结果求10 个整数中最大值在屏幕上输出9*9乘法口诀表二分查找 编写程序数一下 1到 100 的所有整数中出现多少个数字9 #include <stdio.h>in…...
脑机辅助推导算法
目录 一,背景 二,华容道中道 1,问题 2,告诉脑机如何编码一个正方形格子 3,让脑机汇总信息 4,观察图,得到启发式算法 5,根据启发式算法求出具体解 6,可视化 一&am…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
跨平台商品数据接口的标准化与规范化发展路径:淘宝京东拼多多的最新实践
在电商行业蓬勃发展的当下,多平台运营已成为众多商家的必然选择。然而,不同电商平台在商品数据接口方面存在差异,导致商家在跨平台运营时面临诸多挑战,如数据对接困难、运营效率低下、用户体验不一致等。跨平台商品数据接口的标准…...
基于stm32F10x 系列微控制器的智能电子琴(附完整项目源码、详细接线及讲解视频)
注:文章末尾网盘链接中自取成品使用演示视频、项目源码、项目文档 所用硬件:STM32F103C8T6、无源蜂鸣器、44矩阵键盘、flash存储模块、OLED显示屏、RGB三色灯、面包板、杜邦线、usb转ttl串口 stm32f103c8t6 面包板 …...
LUA+Reids实现库存秒杀预扣减 记录流水 以及自己的思考
目录 lua脚本 记录流水 记录流水的作用 流水什么时候删除 我们在做库存扣减的时候,显示基于Lua脚本和Redis实现的预扣减 这样可以在秒杀扣减的时候保证操作的原子性和高效性 lua脚本 // ... 已有代码 ...Overridepublic InventoryResponse decrease(Inventor…...
CMS内容管理系统的设计与实现:多站点模式的实现
在一套内容管理系统中,其实有很多站点,比如企业门户网站,产品手册,知识帮助手册等,因此会需要多个站点,甚至PC、mobile、ipad各有一个站点。 每个站点关联的有站点所在目录及所属的域名。 一、站点表设计…...
