下面给你一份 《使用 .NET 标准库实现多任务并行处理的详细过程(最完整教程)》,完全基于 .NET Standard / .NET Core / .NET 5–8 通用的标准库 API(无任何第三方库)。

内容包括 Task、线程池、Parallel、同步机制、最佳实践等,全栈可用。


⭐ 一、.NET 标准库并行能力总览

.NET 提供以下标准库用来实现并行程序:

技术命名空间场景
Task / async-awaitSystem.Threading.Tasks现代异步与并行任务
Task.Run()System.Threading.Tasks线程池后台任务
Parallel.For / Parallel.ForEachSystem.Threading.Tasks.ParallelCPU 密集型循环并行
ThreadPoolSystem.Threading超低级手动控制线程池
ThreadSystem.Threading最底层线程控制
锁(lock, Monitor)System.Threading多线程同步
并发集合System.Collections.Concurrent安全数据结构

👇 以下将手把手深入讲解。


⭐ 二、最推荐的方式:Task + async/await

✔ 1. 启动一个后台任务

using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        Task task = Task.Run(() =>
        {
            Console.WriteLine("运行任务...");
        });

        await task;
        Console.WriteLine("任务完成");
    }
}

✔ 使用线程池
✔ 自动调度
✔ 最佳实践


✔ 2. 带返回值的任务

Task<int> task = Task.Run(() =>
{
    return 123;
});

int result = await task;
Console.WriteLine(result);


✔ 3. 多个任务并行执行(WhenAll)

var tasks = new[]
{
    Task.Run(() => DoWork(1)),
    Task.Run(() => DoWork(2)),
    Task.Run(() => DoWork(3))
};

await Task.WhenAll(tasks);
Console.WriteLine("所有任务完成");


✔ 4. 多任务并行 + 返回值

var tasks = Enumerable.Range(1, 5)
    .Select(i => Task.Run(() => i * 10));

int[] results = await Task.WhenAll(tasks);

Console.WriteLine(string.Join(",", results));


⭐ 三、Parallel.For / Parallel.ForEach(CPU 密集型)

适用:
✔ 图像处理
✔ 数据处理
✔ CPU 计算
✔ 批量任务并行

✔ Parallel.For

Parallel.For(0, 10, i =>
{
    Console.WriteLine($"任务 {i} 在线程 {Task.CurrentId}");
});


✔ Parallel.ForEach

var list = Enumerable.Range(1, 10);

Parallel.ForEach(list, i =>
{
    Console.WriteLine($"处理 {i}");
});

特点:
✔ 使用多个 CPU 核心
✔ 自动负载均衡
✔ 自动线程池调度


⭐ 四、Task + Parallel 混合使用(企业级常用)

await Task.Run(() =>
{
    Parallel.ForEach(files, file =>
    {
        ProcessFile(file);
    });
});

✔ 将 CPU 密集任务丢到后台
✔ Parallel 在内部使用多核执行


⭐ 五、线程池(ThreadPool)

如果你需要更底层:

ThreadPool.QueueUserWorkItem(_ =>
{
    Console.WriteLine("线程池任务");
});

适用:
✔ 高性能后台执行
✔ 不关心返回值
✔ 极轻量

一般不推荐直接用,Task 已经封装得足够好。


⭐ 六、Thread(最底层,不建议常用)

var thread = new Thread(() =>
{
    Console.WriteLine("新线程执行");
});
thread.Start();
thread.Join();

适用:
✔ 极特殊情况
✔ 必须指定 STA/MTA
✔ 必须真实操作线程生命周期

平常用 Task 就够了。


⭐ 七、线程同步(lock、Monitor)

当多个任务访问共享变量时要加锁。

private static object locker = new object();
private static int counter = 0;

Parallel.For(0, 10000, i =>
{
    lock (locker)
    {
        counter++;
    }
});

线程安全输出:

Console.WriteLine(counter);


⭐ 八、使用并发集合(推荐替代锁)

.NET 标准库提供线程安全集合:

  • ConcurrentDictionary
  • ConcurrentQueue
  • ConcurrentBag
  • ConcurrentStack

示例:

var dict = new ConcurrentDictionary<int, string>();

Parallel.For(0, 100, i =>
{
    dict[i] = $"Value {i}";
});

无需加锁 → 性能高。


⭐ 九、完整案例:多任务爬取网页(并行 + IO 异步)

static async Task Main()
{
    var urls = new[]
    {
        "https://example.com",
        "https://google.com",
        "https://microsoft.com"
    };

    var tasks = urls.Select(async url =>
    {
        using var http = new HttpClient();
        string html = await http.GetStringAsync(url);
        Console.WriteLine($"{url} 大小 = {html.Length}");
        return html.Length;
    });

    int[] results = await Task.WhenAll(tasks);

    Console.WriteLine("全部完成,总字节数:" + results.Sum());
}

✔ 完全并行
✔ 自动控制并行度
✔ 全 IO 异步
✔ 可跨平台


⭐ 十、最佳实践总结

场景推荐方式
普通后台任务Task.Run
等待多个任务完成Task.WhenAll
CPU 密集型循环Parallel.For / Parallel.ForEach
高级、稳健并行计算Task + Parallel
修改共享变量lock / 并发集合
超底层控制ThreadPool / Thread