基本概念
CancellationTokenSource 是一个类,用于创建一个取消令牌 (CancellationToken),并通过该令牌来通知一个或多个异步操作取消请求。CancellationToken 是一个结构体,用于传递取消通知。
创建 CancellationTokenSource
首先,你需要创建一个 CancellationTokenSource 对象。
1
2
3
4
5
6
7
8
9
10
11
using System.Threading;
public class CancellationTokenExample
{
private CancellationTokenSource tokenSource;
public void Initialize()
{
tokenSource = new CancellationTokenSource();
}
}
获取 CancellationToken
从 CancellationTokenSource 获取 CancellationToken 对象。
1
2
3
4
5
6
7
8
9
10
11
12
using System.Threading;
public class CancellationTokenExample
{
private CancellationTokenSource tokenSource;
public void Initialize()
{
tokenSource = new CancellationTokenSource();
CancellationToken token = tokenSource.Token;
}
}
在异步方法中使用 CancellationToken
在异步方法中使用 CancellationToken 来检查取消请求,并在需要时抛出 OperationCanceledException。
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
using System;
using System.Threading;
using System.Threading.Tasks;
using Cysharp.Threading.Tasks; // 如果使用 UniTask
public class CancellationTokenExample : MonoBehaviour
{
private CancellationTokenSource tokenSource;
public async void StartLongRunningTask()
{
Initialize();
CancellationToken token = tokenSource.Token;
try
{
await LongRunningTask(token);
}
catch (OperationCanceledException)
{
Debug.Log("任务已被取消");
}
}
private async UniTask LongRunningTask(CancellationToken token)
{
for (int i = 0; i < 10; i++)
{
token.ThrowIfCancellationRequested(); // 检查取消请求并抛出异常
// 模拟长时间运行的任务
await UniTask.Delay(1000, cancellationToken: token);
Debug.Log($"任务进行中: 第 {i + 1} 次");
}
}
private void Initialize()
{
tokenSource = new CancellationTokenSource();
}
private void OnClickCancelBtn()
{
if (tokenSource != null)
{
tokenSource.Cancel();
tokenSource.Dispose();
tokenSource = null;
}
}
void Start()
{
StartLongRunningTask();
}
void OnDestroy()
{
if (tokenSource != null)
{
tokenSource.Cancel();
tokenSource.Dispose();
}
}
}
详细步骤
创建 CancellationTokenSource:
声明一个 CancellationTokenSource 对象。
1
private CancellationTokenSource tokenSource;
初始化 CancellationTokenSource:
在某个方法中(例如 Start 方法)初始化 CancellationTokenSource。
1
2
3
4
private void Initialize()
{
tokenSource = new CancellationTokenSource();
}
获取 CancellationToken:
从 CancellationTokenSource 获取 CancellationToken 对象。
1
CancellationToken token = tokenSource.Token;
在异步方法中使用 CancellationToken:
在异步方法中,使用 token.ThrowIfCancellationRequested() 检查是否有取消请求。如果有取消请求,会抛出 OperationCanceledException。同时,在需要取消的异步操作中传递 CancellationToken。
1
2
3
4
5
6
7
8
9
10
private async UniTask LongRunningTask(CancellationToken token)
{
for (int i = 0; i < 10; i++)
{
token.ThrowIfCancellationRequested();
await UniTask.Delay(1000, cancellationToken: token);
Debug.Log($"任务进行中: 第 {i + 1} 次");
}
}
取消任务:
在某个事件处理方法中(例如按钮点击事件),调用 tokenSource.Cancel() 来取消任务,并释放资源。
1
2
3
4
5
6
7
8
9
private void OnClickCancelBtn()
{
if (tokenSource != null)
{
tokenSource.Cancel();
tokenSource.Dispose();
tokenSource = null;
}
}
确保资源正确释放:
在对象销毁时确保取消令牌被正确释放,以避免内存泄漏。
1
2
3
4
5
6
7
8
void OnDestroy()
{
if (tokenSource != null)
{
tokenSource.Cancel();
tokenSource.Dispose();
}
}
总结
- 创建 CancellationTokenSource:用于生成取消令牌。
- 获取 CancellationToken:从 CancellationTokenSource 获取令牌。
- 在异步方法中使用 CancellationToken:检查取消请求并抛出异常。
- 取消任务:调用 CancellationTokenSource.Cancel() 来取消任务。
- 确保资源正确释放:在对象销毁时释放 CancellationTokenSource 资源。
通过这些步骤,你可以在 C# 中有效地使用 CancellationTokenSource 来取消异步操作,特别是在 Unity 环境中处理长时间运行的任务时。