任务并行 #

一、Task概述 #

1.1 什么是Task #

Task表示异步操作,是任务并行库(TPL)的核心。

1.2 Task vs Thread #

特性 Task Thread
返回值 支持 不支持
线程池 默认使用 不使用
取消 支持 不支持
组合 支持 不支持

二、创建Task #

2.1 Task.Run #

csharp
Task task = Task.Run(() =>
{
    Console.WriteLine("任务执行中...");
});
task.Wait();

Task<int> task = Task.Run(() =>
{
    Thread.Sleep(1000);
    return 42;
});
int result = task.Result;

2.2 Task构造函数 #

csharp
var task = new Task(() =>
{
    Console.WriteLine("任务执行中...");
});
task.Start();
task.Wait();

var task = new Task<int>(() =>
{
    return Calculate();
});
task.Start();
int result = task.Result;

2.3 TaskFactory #

csharp
var factory = Task.Factory;

Task task = factory.StartNew(() =>
{
    Console.WriteLine("任务执行中...");
});

Task<int> task = factory.StartNew(() => Calculate());

三、Task返回值 #

3.1 Task #

csharp
public async Task<int> CalculateAsync()
{
    await Task.Delay(1000);
    return 42;
}

Task<int> task = Task.Run(() =>
{
    Thread.Sleep(1000);
    return Enumerable.Range(1, 100).Sum();
});

int result = await task;
int result = task.Result;

3.2 获取结果 #

csharp
Task<int> task = Task.Run(() => Calculate());

task.Wait();
int result = task.Result;

int result = await task;

if (task.IsCompletedSuccessfully)
{
    int result = task.Result;
}

四、Task组合 #

4.1 Task.WhenAll #

csharp
var tasks = new List<Task<int>>();
for (int i = 0; i < 10; i++)
{
    int taskId = i;
    tasks.Add(Task.Run(() => Calculate(taskId)));
}

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

Task.WaitAll(tasks.ToArray());

4.2 Task.WhenAny #

csharp
var tasks = new List<Task<int>>
{
    Task.Run(() => SlowCalculate()),
    Task.Run(() => FastCalculate())
};

Task<int> firstCompleted = await Task.WhenAny(tasks);
int result = await firstCompleted;

Task<int> completedTask = await Task.WhenAny(tasks);
if (completedTask == tasks[0])
{
    Console.WriteLine("第一个任务先完成");
}

4.3 ContinueWith #

csharp
Task<int> task = Task.Run(() => Calculate());

task.ContinueWith(t =>
{
    Console.WriteLine($"结果: {t.Result}");
});

task.ContinueWith(t =>
{
    Console.WriteLine($"错误: {t.Exception?.Message}");
}, TaskContinuationOptions.OnlyOnFaulted);

task.ContinueWith(t =>
{
    Console.WriteLine("取消");
}, TaskContinuationOptions.OnlyOnCanceled);

五、Task状态 #

5.1 TaskStatus #

状态 说明
Created 已创建
WaitingForActivation 等待激活
WaitingToRun 等待运行
Running 运行中
WaitingForChildrenToComplete 等待子任务
RanToCompletion 成功完成
Canceled 已取消
Faulted 发生错误

5.2 检查状态 #

csharp
Task<int> task = Task.Run(() => Calculate());

Console.WriteLine($"状态: {task.Status}");
Console.WriteLine($"是否完成: {task.IsCompleted}");
Console.WriteLine($"是否成功: {task.IsCompletedSuccessfully}");
Console.WriteLine($"是否取消: {task.IsCanceled}");
Console.WriteLine($"是否错误: {task.IsFaulted}");

六、Task取消 #

6.1 CancellationToken #

csharp
var cts = new CancellationTokenSource();
CancellationToken token = cts.Token;

Task task = Task.Run(() =>
{
    for (int i = 0; i < 100; i++)
    {
        token.ThrowIfCancellationRequested();
        Thread.Sleep(100);
    }
}, token);

await Task.Delay(1000);
cts.Cancel();

try
{
    await task;
}
catch (OperationCanceledException)
{
    Console.WriteLine("任务已取消");
}

6.2 取消超时 #

csharp
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));

var cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromSeconds(5));

6.3 注册取消回调 #

csharp
var cts = new CancellationTokenSource();
cts.Token.Register(() =>
{
    Console.WriteLine("任务被取消");
});

七、Task异常处理 #

7.1 捕获异常 #

csharp
try
{
    await Task.Run(() =>
    {
        throw new InvalidOperationException("任务错误");
    });
}
catch (InvalidOperationException ex)
{
    Console.WriteLine($"捕获异常: {ex.Message}");
}

7.2 AggregateException #

csharp
var tasks = new[]
{
    Task.Run(() => throw new Exception("错误1")),
    Task.Run(() => throw new Exception("错误2"))
};

try
{
    Task.WaitAll(tasks);
}
catch (AggregateException ex)
{
    foreach (var inner in ex.InnerExceptions)
    {
        Console.WriteLine(inner.Message);
    }
}

7.3 Flatten异常 #

csharp
try
{
    Task.WaitAll(tasks);
}
catch (AggregateException ex)
{
    ex.Flatten().Handle(e =>
    {
        Console.WriteLine(e.Message);
        return true;
    });
}

八、Parallel类 #

8.1 Parallel.For #

csharp
Parallel.For(0, 100, i =>
{
    Console.WriteLine($"处理 {i}");
});

Parallel.For(0, 100, new ParallelOptions { MaxDegreeOfParallelism = 4 }, i =>
{
    Process(i);
});

8.2 Parallel.ForEach #

csharp
var data = Enumerable.Range(0, 100).ToList();

Parallel.ForEach(data, item =>
{
    Process(item);
});

Parallel.ForEach(data, new ParallelOptions { MaxDegreeOfParallelism = 4 }, item =>
{
    Process(item);
});

8.3 Parallel.Invoke #

csharp
Parallel.Invoke(
    () => DoWork1(),
    () => DoWork2(),
    () => DoWork3()
);

九、总结 #

任务并行要点:

要点 说明
Task.Run 创建任务
Task 带返回值
WhenAll 等待所有
WhenAny 等待任一
CancellationToken 取消任务
Parallel 并行循环

下一步,让我们学习异步编程!

最后更新:2026-03-26