在 C# 中,Task 是用于实现异步编程和多线程操作的核心类型,属于 System.Threading.Tasks
命名空间。它基于 任务并行库(TPL, Task Parallel Library),提供了一种更高级、更灵活的线程管理方式,相比传统的 Thread
类更高效且易于使用。
以下是关于 C# Task 线程 的关键概念和用法:
1. Task 的基本使用
创建和启动 Task
方式 1:
Task.Run()
(推荐)Task.Run(() => { // 在线程池中执行的任务代码 Console.WriteLine("Task running on thread: " + Thread.CurrentThread.ManagedThreadId); });
方式 2:
Task.Factory.StartNew()
Task.Factory.StartNew(() => { // 任务逻辑 }, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
方式 3:直接实例化(需手动启动)
var task = new Task(() => Console.WriteLine("Task started")); task.Start(); // 显式启动
2. 异步等待(async/await)
通过 async/await
可以更简洁地处理异步操作:
public async Task DoWorkAsync()
{
await Task.Run(() => {
// 模拟耗时操作
Thread.Sleep(1000);
});
Console.WriteLine("Work completed!");
}
3. Task 的返回值
- 使用
Task<TResult>
:任务可以返回结果。
Task<int> task = Task.Run(() => {
return 42; // 返回结果
});
int result = await task; // 获取结果
4. 任务控制与协调
等待多个任务
Task.WaitAll()
:阻塞直到所有任务完成。Task.WhenAll()
:返回一个任务,该任务在所有参数任务完成后完成。
Task task1 = Task.Run(() => { /* ... */ });
Task task2 = Task.Run(() => { /* ... */ });
await Task.WhenAll(task1, task2); // 非阻塞等待
异常处理
try
{
await Task.Run(() => { throw new Exception("Oops!"); });
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
5. 取消任务(CancellationToken)
通过 CancellationTokenSource
实现任务取消:
var cts = new CancellationTokenSource();
Task task = Task.Run(() => {
while (true)
{
if (cts.Token.IsCancellationRequested)
{
break; // 优雅退出
}
// 工作代码
}
}, cts.Token);
// 外部取消任务
cts.Cancel();
6. TaskScheduler与线程管理
- 默认行为:
Task
默认使用线程池线程(避免频繁创建/销毁线程)。 - 自定义调度:可通过
TaskScheduler
控制任务的执行上下文(如UI线程)。
7. 与Thread的区别
特性 | Thread | Task |
---|---|---|
资源开销 | 较高(独占OS线程) | 较低(基于线程池) |
返回值 | 不支持 | 支持 (Task<TResult> ) |
异常处理 | 需手动捕获 | 可通过AggregateException统一处理 |
协调能力 | 依赖低级别同步原语 | 内置Wait/WhenAll等高级API |
8. 最佳实践
- 优先用
Task.Run
而非new Thread()
。 - 避免阻塞操作:尽量使用
async/await
而非.Wait()
或.Result
(可能导致死锁)。 - 合理配置并发度:对于CPU密集型任务,可通过
Parallel.For
或设置MaxDegreeOfParallelism
。
如果需要进一步了解具体场景的代码示例或深入原理,可以提供更多细节!
内容由零声教学AI助手提供,问题来源于学员提问