跳转到内容

C Sharp Task 基础

来自代码酷

C# Task基础[编辑 | 编辑源代码]

介绍[编辑 | 编辑源代码]

Task是C#异步编程的核心概念之一,属于.NET框架中的System.Threading.Tasks命名空间。它表示一个异步操作,可以用于执行长时间运行的任务而不会阻塞主线程。Task提供了一种更高效的方式来处理并发和并行操作,相比传统的线程(Thread)和线程池(ThreadPool),Task更加轻量级且易于管理。

Task的主要特点包括:

  • 支持异步操作的启动、等待和结果获取。
  • 可以串联多个Task(通过ContinueWithasync/await)。
  • 提供取消、异常处理和进度报告等功能。

Task的基本用法[编辑 | 编辑源代码]

创建和运行Task[编辑 | 编辑源代码]

Task可以通过Task.Runnew 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.WaitTask.WaitAllTask.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.WaitTask.WhenAllTask.WhenAny等待任务完成。
  • 通过ContinueWith串联多个任务。
  • 异常需通过AggregateException处理。

进阶学习建议[编辑 | 编辑源代码]

  • 学习async/await关键字以简化异步代码。
  • 探索TaskCancellationToken实现任务取消。
  • 研究TaskScheduler自定义任务调度逻辑。