代码改变世界

Task里面使用到for的具部变量

  钟铧若岩  阅读(3)  评论(0编辑  收藏  举报
在 C# 里,当你在 for 循环中使用 Task 并且要把 for 循环的变量传递给 Task 时,需要特别注意变量捕获的问题。因为如果不恰当处理,可能会出现所有 Task 都使用循环结束时变量的最终值这种情况。下面为你介绍几种正确的处理方式。

方法一:使用临时变量


在每次循环中创建一个临时变量来存储当前循环的变量值,这样每个 Task 就能捕获到正确的值。示例代码如下:
复制代码
using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        // 定义循环次数
        int loopCount = 5;
        // 用于存储所有任务的数组
        Task[] tasks = new Task[loopCount];

        for (int i = 0; i < loopCount; i++)
        {
            // 创建临时变量,捕获当前循环的 i 值
            int temp = i;
            // 创建一个任务,打印临时变量的值
            tasks[i] = Task.Run(() =>
            {
                Console.WriteLine($"Task 执行,传入的值为: {temp}");
            });
        }

        // 等待所有任务完成
        await Task.WhenAll(tasks);
    }
}
复制代码
代码解释:

 

    1. 在 for 循环里,每次迭代都创建一个临时变量 temp 并把当前的 i 值赋给它。
    2. 接着在 Task.Run 中使用这个临时变量,这样每个 Task 捕获的就是当时 temp 的值。
    3. 最后使用 Task.WhenAll 等待所有任务完成。

方法二:使用 Lambda 表达式参数

 

可以把循环变量作为参数传递给一个委托,从而避免变量捕获问题。示例代码如下:
复制代码
using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        int loopCount = 5;
        Task[] tasks = new Task[loopCount];

        for (int i = 0; i < loopCount; i++)
        {
            // 定义一个匿名方法,接收一个整数参数
            Action<int> action = (index) =>
            {
                Console.WriteLine($"Task 执行,传入的值为: {index}");
            };
            // 以任务的形式运行该匿名方法,并传入当前的 i 值
            tasks[i] = Task.Run(() => action(i));
        }

        await Task.WhenAll(tasks);
    }
}
复制代码
代码解释:

 

    1. 定义了一个 Action<int> 委托 action,它接收一个整数参数。
    2. 在 Task.Run 中调用这个委托并传入当前的 i 值,这样每个 Task 就能正确处理传入的值。
    3. 同样使用 Task.WhenAll 等待所有任务完成。

传递单个变量到 Task.Run 中的 Lambda 表达式


如果你有一个已经定义好的变量,想把它传递给 Task.Run 中的 Lambda 表达式,可直接在 Lambda 里使用该变量。以下是示例代码:

复制代码
using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        // 定义一个变量
        string message = "Hello, Task!";
        // 直接在 Task.Run 中使用 Lambda 表达式并使用变量
        Task task = Task.Run(() =>
        {
            Console.WriteLine(message);
        });

        // 等待任务完成
        await task;
    }
}
复制代码

 

    
        

相关博文:
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示