C Sharp委托、事件、多线程

文章目录

    • 委托(Delegate)—— 你的“遥控器”
    • 事件(Event)—— 安全的“通知系统”
    • 多线程(Multithreading)—— “同时做多件事”

委托(Delegate)—— 你的“遥控器”

是什么?
想象你有一个万能遥控器,可以控制家里的电视、空调、灯光。委托就是这个“遥控器”,它允许你通过一个东西调用多个不同的方法。

为什么需要它?
比如你想写一个程序,让用户点击按钮时执行某些操作,但具体操作可能随时变化。委托可以帮你灵活地“保存”这些操作,随时调用。

怎么用?
步骤 1:定义一个遥控器(委托)
步骤 2:创建具体设备(方法)
步骤 3:用遥控器绑定设备

//1、声明一个委托类型,它只能“控制”无返回值、参数为string的方法
public delegate void MyRemoteControl(string msg);

//2、创建具体设备(方法)
public void TurnOnTv(string msg){
	Console.WriteLine("打开电视:"+msg);
}
public void TurnOffLight(string msg)
{
	Console.WriteLine("关闭灯光:" + msg);
}
//3、用遥控器绑定设备
void Main()
{
	// 绑定到电视
	MyRemoteControl myRemote =new MyRemoteControl(TurnOnTv);
	myRemote ("播放喜洋洋与灰太狼");
	//多播:遥控器同时控制多个设备
	myRemote+=TurnOffLight;
	myRemote("睡觉&看球赛");
}
打开电视:播放喜洋洋与灰太狼
打开电视:睡觉&看球赛
关闭灯光:睡觉&看球赛

事件(Event)—— 安全的“通知系统”

是什么?
事件是委托的升级版。比如你家门铃(事件),别人只能按门铃(触发事件),但不能直接拆掉你的门铃线路(保证安全)。

为什么需要它?
安全:外部代码只能订阅(+=)或取消订阅(-=),不能直接清空所有绑定。

场景:比如游戏中的“玩家死亡时通知所有敌人停止攻击”。

怎么用?

//步骤 1:定义一个门铃(事件)
public class Doorbell{
	//声明一个事件(基于委托)
	public event Action<string> OnRing;
	
	public void Ring(){
		//出发时间(按门铃)
		OnRing?.Invoke("有人按门铃啦");// ?. 防止未订阅时出错
	}
}
//步骤 2:住户的反应(订阅事件)
public class Resident{
	public void ReactToRing(string msg){
		Console.WriteLine("住户:"+msg+"我去开门!");
	}
}
//步骤 3:使用门铃
void Main()
{
	Doorbell doorbell = new Doorbell();
	Resident resident = new Resident();
	//住户订阅门铃时间
	doorbell.OnRing +=resident.ReactToRing;
	//有人按门铃
	doorbell.Ring();
}
住户:有人按门铃啦我去开门!

?.安全检查,等价于

if (OnRing != null) {
    OnRing.Invoke(...); 
}

Invoke:正式“触发事件”

多线程(Multithreading)—— “同时做多件事”

是什么?
假设你在煮饭(主线程),同时还要切菜(子线程)。多线程就是让程序能“同时”处理多个任务,提升效率。

为什么需要它?
防止主界面卡死(比如下载文件时不冻结界面)。
充分利用CPU多核性能。

怎么用?

//方法 1:传统方式(Thread)—— 手动控制
void Main()
{
	Thread thread = new Thread(() => {
		Console.WriteLine("子线程:我在切菜");
	});
	thread.Start();
	Console.WriteLine("主线程:我在煮饭");
}
主线程:我在煮饭
子线程:我在切菜
//方法 2:现代方式(Task)—— 更简单高效
void Main()
{
	Task.Run(() =>
	{
		Console.WriteLine("子线程:我在烧水!");
	});
	Console.WriteLine("主线程:我在炒菜!");
}
主线程:我在炒菜!
子线程:我在烧水!
//方法 3:异步编程(async/await)—— 等待不阻塞
public async Task CookDinner(){
	Console.WriteLine("开始做饭");

	//异步煮饭(不阻塞)
	await Task.Run(() =>{
		Thread.Sleep(2000);//2s
		Console.WriteLine("饭煮好了");
	});
	Console.WriteLine("开始炒菜");//煮晚饭开始
	
	//await CookDinner();//调用
}

async Task Main(){
	await CookDinner();
}
开始做饭
饭煮好了
开始炒菜

() => {}这是一个 Lambda 表达式,相当于快速写一个“匿名方法”。
():参数列表(无参数时留空)。
=>:箭头符号,表示“执行后面的代码”。
{}:代码块,具体要执行的任务。

Thread thread = new Thread(() => { 
    Console.WriteLine("切菜"); 
}); // 直接把任务写在括号里

相当于:

void CutVegetables() {
    Console.WriteLine("切菜");
}
Thread thread = new Thread(CutVegetables); // 传入方法名

委托和事件的区别?
委托是功能基础,事件是加了限制的委托(类似public和private的区别)。

多线程会加快程序速度吗?
不一定!如果任务简单,切换线程的开销可能反而更慢。适合处理耗时操作(如文件读写)。

async/await 和 Task 的区别?
async/await 是基于 Task 的语法糖,让异步代码看起来像同步代码,更易读。

你可能感兴趣的:(#,c,sharp,c语言,开发语言)