C Sharp Task 基础
外观
C# Task基础[编辑 | 编辑源代码]
介绍[编辑 | 编辑源代码]
Task是C#异步编程的核心概念之一,属于.NET框架中的System.Threading.Tasks
命名空间。它表示一个异步操作,可以用于执行长时间运行的任务而不会阻塞主线程。Task提供了一种更高效的方式来处理并发和并行操作,相比传统的线程(Thread)和线程池(ThreadPool),Task更加轻量级且易于管理。
Task的主要特点包括:
- 支持异步操作的启动、等待和结果获取。
- 可以串联多个Task(通过
ContinueWith
或async/await
)。 - 提供取消、异常处理和进度报告等功能。
Task的基本用法[编辑 | 编辑源代码]
创建和运行Task[编辑 | 编辑源代码]
Task可以通过Task.Run
或new Task
来创建。以下是两种方式的示例:
using System;
using System.Threading.Tasks;
class Program
{
static void Main()
{
// 方式1:使用Task.Run启动一个任务
Task task1 = Task.Run(() =>
{
Console.WriteLine("Task1 正在运行...");
});
// 方式2:显式创建并启动Task
Task task2 = new Task(() =>
{
Console.WriteLine("Task2 正在运行...");
});
task2.Start();
// 等待任务完成
Task.WaitAll(task1, task2);
Console.WriteLine("所有任务完成!");
}
}
输出:
Task1 正在运行... Task2 正在运行... 所有任务完成!
带返回值的Task[编辑 | 编辑源代码]
Task可以返回结果,使用Task<TResult>
泛型类。例如:
using System;
using System.Threading.Tasks;
class Program
{
static void Main()
{
Task<int> task = Task.Run(() =>
{
Console.WriteLine("计算中...");
return 42; // 返回一个整数值
});
// 获取任务结果(会阻塞直到任务完成)
int result = task.Result;
Console.WriteLine($"计算结果: {result}");
}
}
输出:
计算中... 计算结果: 42
Task的等待和延续[编辑 | 编辑源代码]
等待Task完成[编辑 | 编辑源代码]
可以使用Task.Wait
、Task.WaitAll
或Task.WaitAny
来同步等待任务完成。
Task task1 = Task.Run(() => { Thread.Sleep(1000); Console.WriteLine("Task1完成"); });
Task task2 = Task.Run(() => { Thread.Sleep(2000); Console.WriteLine("Task2完成"); });
Task.WaitAll(task1, task2); // 等待所有任务完成
Console.WriteLine("所有任务完成!");
输出:
Task1完成 Task2完成 所有任务完成!
使用ContinueWith串联任务[编辑 | 编辑源代码]
ContinueWith
允许在一个Task完成后自动启动另一个Task。
Task<int> task = Task.Run(() =>
{
Console.WriteLine("第一个任务运行");
return 10;
});
Task continuationTask = task.ContinueWith((previousTask) =>
{
Console.WriteLine($"前一个任务的结果: {previousTask.Result}");
});
continuationTask.Wait();
输出:
第一个任务运行 前一个任务的结果: 10
异常处理[编辑 | 编辑源代码]
Task中的异常会被捕获并存储在Task.Exception
属性中。可以通过try-catch
块或检查Exception
属性来处理异常。
Task task = Task.Run(() =>
{
throw new InvalidOperationException("任务出错!");
});
try
{
task.Wait();
}
catch (AggregateException ex)
{
foreach (var innerEx in ex.InnerExceptions)
{
Console.WriteLine($"捕获异常: {innerEx.Message}");
}
}
输出:
捕获异常: 任务出错!
实际应用案例[编辑 | 编辑源代码]
并行下载文件[编辑 | 编辑源代码]
以下示例展示如何使用Task并行下载多个文件:
using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
string[] urls =
{
"https://example.com/file1.txt",
"https://example.com/file2.txt",
"https://example.com/file3.txt"
};
HttpClient client = new HttpClient();
Task[] downloadTasks = new Task[urls.Length];
for (int i = 0; i < urls.Length; i++)
{
string url = urls[i];
downloadTasks[i] = Task.Run(async () =>
{
string content = await client.GetStringAsync(url);
Console.WriteLine($"下载完成: {url}, 长度: {content.Length}");
});
}
await Task.WhenAll(downloadTasks);
Console.WriteLine("所有文件下载完成!");
}
}
输出(假设文件存在):
下载完成: https://example.com/file1.txt, 长度: 1024 下载完成: https://example.com/file2.txt, 长度: 2048 下载完成: https://example.com/file3.txt, 长度: 512 所有文件下载完成!
总结[编辑 | 编辑源代码]
Task是C#异步编程的核心组件,提供了高效的任务调度和管理机制。通过Task,开发者可以轻松实现并行操作、异步等待和异常处理。结合async/await
(将在后续章节介绍),Task能进一步简化异步代码的编写。
关键点回顾[编辑 | 编辑源代码]
- Task表示一个异步操作,可通过
Task.Run
或构造函数创建。 - 使用
Task.Wait
、Task.WhenAll
或Task.WhenAny
等待任务完成。 - 通过
ContinueWith
串联多个任务。 - 异常需通过
AggregateException
处理。
进阶学习建议[编辑 | 编辑源代码]
- 学习
async/await
关键字以简化异步代码。 - 探索
TaskCancellationToken
实现任务取消。 - 研究
TaskScheduler
自定义任务调度逻辑。