C# 中 Task.Run() 完全指南:从原理到避坑实践

一、Task.Run() 是什么

Task.Run() 是 .NET Framework 4.5 引入的将工作项排队到线程池的便捷方法。它的本质是把一个委托(Action 或 Func)抛到 ThreadPool 的队列中,由线程池线程异步执行,并返回一个 TaskTask<T> 作为异步操作的句柄。

// 无返回值
Task task = Task.Run(() => DoWork());

// 有返回值
Task<int> task = Task.Run(() => Calculate(3, 5));
int result = await task;  // result = 8

一句话定义:Task.Run() = 把一段代码丢到后台线程执行,并给你一个可以 await 的凭证。


二、为什么需要 Task.Run()

在 Task.Run() 出现之前,开发者需要这样写:

// .NET 4.0 时代
Task.Factory.StartNew(() => DoWork(), CancellationToken.None, 
    TaskCreationOptions.None, TaskScheduler.Default);

繁琐且容易出错(比如默认调度器可能不是线程池)。Task.Run() 就是 Task.Factory.StartNew()安全快捷版,它:

  • 默认使用 TaskScheduler.Default(即线程池)

  • 自动解包嵌套 Task(Unwrap)

  • 默认 DenyChildAttach(防止子任务意外附加)

  • 代码更简洁


三、基础用法

1. 执行 CPU 密集型工作

public async Task ProcessDataAsync()
{
    // 把 CPU 密集计算丢到后台
    int result = await Task.Run(() =>
    {
        int sum = 0;
        for (int i = 0; i < 100000000; i++)
            sum += i;
        return sum;
    });
    
    Console.WriteLine($"计算结果: {result}");
}

2. 并行执行多个任务

public async Task RunParallelAsync()
{
    Task<int> task1 = Task.Run(() => FetchDataFromDb());
    Task<int> task2 = Task.Run(() => FetchDataFromApi());
    Task<int> task3 = Task.Run(() => CalculateHash());

    // 同时等待所有任务完成
    int[] results = await Task.WhenAll(task1, task2, task3);
    
    Console.WriteLine($"DB: {results[0]}, API: {results[1]}, Hash: {results[2]}");
}

3. 带取消功能的后台任务

public async Task RunWithCancellationAsync(CancellationToken cancellationToken)
{
    try
    {
        int result = await Task.Run(() =>
        {
            for (int i = 0; i < 100; i++)
            {
                cancellationToken.ThrowIfCancellationRequested();
                Thread.Sleep(100);  // 模拟工作
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

A_nanda

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值