C#中Task的详细用法
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(最常用)static void Main(string[] args){// 1. 使用构造函数(需要手动启动)Task task1 = new Task(() =>{Thread.Sleep(100);Console.WriteLine($"hello,task1的线程ID为{Thread.CurrentThread.ManagedThreadId}");});task1.Start();// 2. 使用 Task.Factory.StartNewTask 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<string> task1 = new Task<string>(() =>
{Thread.Sleep(100);return ($"task1的线程ID为{Thread.CurrentThread.ManagedThreadId}");});
task1.Start();Task<int> task2 = Task.Factory.StartNew(() =>
{Thread.Sleep(100);return 222;
});Task<bool> task3 = Task.Run(() =>
{Thread.Sleep(100);return true;
});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# 异步编程的基础,合理使用可提升程序性能和响应能力。
