Unity常见的动态资源加载

Unity常用的插件

DoTween

热更新的底层原理

包括常用的热更新矿建,ILRunTime,华佗,XLua,ToLua

常用的开源框架

UGF

GF

工厂模式

事件和委托的区别

委托(delegate)和事件(event)在 C# 中关系非常密切,事件是建立在委托基础上的一种封装机制。委托本质上是一种类型安全的方法引用,它允许程序把方法当作数据来存储和传递。通过委托,可以在运行时决定调用哪个方法,而不是在代码中提前写死调用逻辑。同时,一个委托还可以引用多个方法,当委托被调用时,这些方法会按照顺序依次执行,因此委托常被用于实现回调机制或通知机制。

但是,如果一个委托被公开给外部使用,外部代码就可以随意操作这个委托,例如重新赋值、清空委托、或者直接调用委托。这会导致类的内部行为可能被外部破坏,使程序的控制权变得混乱。为了解决这个问题,C# 引入了事件(event)。

事件实际上是对委托的一种安全封装。使用事件后,外部代码只能对事件进行订阅(+=)或取消订阅(-=),而不能直接调用事件,也不能重新赋值或清空事件。只有声明事件的类内部才可以触发事件,从而保证事件的触发时机完全由类自身控制。

因此可以理解为:委托是一种保存和调用方法的机制,而事件是在委托基础上实现的一种更安全的通知机制,用于实现发布—订阅模式。 简单来说,事件就是“受限制的委托”,它限制了外部对委托的直接操作,使程序结构更加安全和清晰。

异步编程

你的理解整体是有一定道理的,但有几个地方需要稍微修正和补充。我帮你整理成一段更准确、结构更清晰的说明(保持偏文字说明的形式)。


在 C# 中,**异步编程(Asynchronous Programming)**主要用于处理那些可能耗时较长的操作,例如网络请求、文件读写或数据库访问等。通过异步编程,可以避免主线程被长时间阻塞,从而提高程序的响应能力。在很多情况下,异步编程也会与并发操作结合使用,例如多线程技术。

实现并发的一种方式是使用多线程(Multithreading)。在 C# 中可以通过 ThreadTask、线程池等方式创建新的执行线程。当程序创建新的线程时,这个线程会与主线程同时运行,各自执行自己的任务,从而实现真正意义上的并发。在多核 CPU 的情况下,不同线程甚至可以在不同核心上同时执行,从而提高程序的执行效率。

不过需要注意的是,Task 并不一定等同于创建新线程。Task 本质上是一种更高级的异步任务抽象,它通常会由 线程池(ThreadPool) 来调度执行,而不是每次都创建一个新的线程。这样可以减少线程创建和销毁带来的开销,因此在现代 C# 异步编程中通常推荐使用 Task 以及 async/await 模式,而不是直接使用 Thread

除了真正的多线程并发之外,还存在一种类似并发的执行方式,通常被称为协程(Coroutine)或伪并发。协程并不会创建新的线程,而是在同一个线程中通过任务切换来实现多个任务交替执行。程序在运行过程中会在不同任务之间进行切换,每个任务只执行一小段,然后让出执行权,再由调度器安排其他任务运行。从宏观上看,多个任务像是在同时进行,但实际上在某一时刻仍然只有一个任务在执行。

这种机制依赖于 CPU 的时间片调度或程序内部的任务调度。例如在一些游戏引擎(如 Unity)中,协程就是通过在主线程中分阶段执行任务来实现的,它不会开启新的线程,而是利用帧更新机制在不同时间点继续执行未完成的逻辑。

因此,总体来说:

  • 多线程并发:通过创建多个线程,使多个任务能够同时执行(在多核 CPU 上可能真正同时运行)。
  • 异步任务(Task/async/await):一种更现代的异步编程方式,通常由线程池调度,不一定每次都创建新线程。
  • 协程或伪并发:不创建新线程,而是在同一线程中通过任务切换实现多个任务交替执行。

通过这些机制,C# 可以在保证程序响应性的同时,提高资源利用率,并更高效地处理大量耗时操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
static async Task Main()
{
// 1. 最基本的Task创建和运行
Task task = Task.Run(() =>
{
Console.WriteLine($"Task运行在线程ID: {Thread.CurrentThread.ManagedThreadId}");
});

// 2. 等待Task完成
await task;

// 3. async/await示例
await AsyncMethod();

// 4. 创建新线程
Thread thread = new Thread(() =>
{
Console.WriteLine($"Thread运行在线程ID: {Thread.CurrentThread.ManagedThreadId}");
});
thread.Start();
thread.Join(); // 等待线程结束

Console.WriteLine("所有任务完成");
}

static async Task AsyncMethod()
{
Console.WriteLine("Async方法开始");
await Task.Delay(100); // 模拟异步操作
Console.WriteLine("Async方法结束");
}
}
Task运行在线程ID: 4
Async方法开始
Async方法结束
Thread运行在线程ID: 6
所有任务完成