Task 概述
Task 是 .NET 中用于表示异步操作的类,属于 System.Threading.Tasks 命名空间。它封装了一个异步操作,提供状态管理、取消支持、延续任务等功能,是编写异步代码的核心组件之一。
Task 的核心特性
- 异步执行
:Task 可以在后台线程或线程池中运行,避免阻塞主线程。 - 状态跟踪
:提供 Status属性(如RanToCompletion、Faulted、Canceled)。 - 结果获取
:通过 Result属性获取返回值(泛型Task<T>)。 - 取消支持
:结合 CancellationToken实现任务取消。 - 延续任务
:通过 ContinueWith定义任务完成后的操作。
常用使用方法
创建并启动 Task
使用 Task.Run 或 Task.Factory.StartNew 启动一个后台任务:
// 1. 使用 Task.Run(最常用)
staticvoidMain(string[] args)
{
// 1. 使用构造函数(需要手动启动)
Task task1 = new Task(() =>
{
Thread.Sleep(100);
Console.WriteLine($"hello,task1的线程ID为{Thread.CurrentThread.ManagedThreadId}");
});
task1.Start();
// 2. 使用 Task.Factory.StartNew
Task task2 = Task.Factory.StartNew(() =>
{
Thread.Sleep(100);
Console.WriteLine($"hello,task2的线程ID为{Thread.CurrentThread.ManagedThreadId}");
});
//3.使用 Task.Run(最常用)
Task task3 = Task.Run(() =>
{
Thread.Sleep(100);
Console.WriteLine($"hello,task3的线程ID为{Thread.CurrentThread.ManagedThreadId}");
});
Console.WriteLine($"主线程ID为{Thread.CurrentThread.ManagedThreadId}");
Console.ReadKey();
}
执行结果如下,可以看到先输出了 “主线程ID为1”,说明了Task不会阻塞主线程,并且线程执行是无序的

我们也可以创建有返回值的Task,用法和没有返回值的基本一致,,代码如下:
Task task1 = new Task (() =>
{
Thread.Sleep(100);
return ($"task1的线程ID为{Thread.CurrentThread.ManagedThreadId}");
});
task1.Start();
Task task2 = Task.Factory.StartNew(() =>
{
Thread.Sleep(100);
return222;
});
Task task3 = Task.Run(() =>
{
Thread.Sleep(100);
returntrue;
});
Console.WriteLine($"主线程ID为{Thread.CurrentThread.ManagedThreadId}");
Console.WriteLine(task1.Result);
Console.WriteLine(task2.Result);
Console.WriteLine(task3.Result);
Console.ReadKey();
执行结果如下:

task.Resut获取结果时会阻塞主线程,即如果task没有执行完成,会等待task执行完成获取到Result,所以这里是顺序执行。
等待 Task 完成
通过 Wait、WaitAll 或 await 等待任务完成:
var task = Task.Run(()=>{
Thread.Sleep(1000);
return"完成";
});
// 阻塞等待
task.Wait();
Console.WriteLine(task.Result);
// 异步等待(需在 async 方法中使用)
string result = await task;
处理 Task 返回值
使用泛型 Task<T> 获取返回值:
Task<int> task = Task.Run(()=>{
return 42;
});
Console.WriteLine(task.Result);// 输出 42
任务延续(ContinueWith)
在任务完成后执行后续操作:
Task.Run(()=>{
Console.WriteLine("任务1");
}).ContinueWith(prevTask =>{
Console.WriteLine("任务2");
});
取消 Task
通过 CancellationToken 实现任务取消:
var cts = new CancellationTokenSource();
var task = Task.Run(()=>{
while(true){
cts.Token.ThrowIfCancellationRequested();
Thread.Sleep(100);
}
}, cts.Token);
cts.CancelAfter(1000);// 1秒后取消
异常处理
通过 AggregateException 捕获任务异常:
try{
Task.Run(()=>throw new Exception("错误")).Wait();
}catch(AggregateException ex){
Console.WriteLine(ex.InnerException.Message);
}
最佳实践
避免 Task.Result或Task.Wait导致死锁(尤其在 UI 线程中)。使用 Task.WhenAll并行执行多个任务:
Task<int> task1 = Task.Run(()=>1);
Task<int> task2 = Task.Run(()=>2);
int[] results = await Task.WhenAll(task1, task2);
Task 是现代 C# 异步编程的基础,合理使用可提升程序性能和响应能力。
Mikel