C# Task.Run调用外部参数For循环 i

4 篇文章 0 订阅
		static void Main(string[] args)
        {
            Task[] tasks = new Task[10];
            int[] numbers = new int[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
            for (int i = 0; i < tasks.Length; i++)
            {
     
                tasks[i] = Task.Run(() =>
                {
                    Console.WriteLine("Number:{0}", numbers[i]); // 索引超出了数组界限。i会一直是10
                });
            }
            Console.ReadLine();
        }

原因解析:

Task.Run是在新的线程中异步执行的,在 for 循环中 Task 并不会立即执行,“i会一直是10”说明 for 循环结束后,Task 才开始执行,这时 i 的值正好是 10 。

解决办法:

这说明 i 的值没有被捕获到 Task 的执行上下文中,也就是说 i 变量的值不在捕获范围内,要想让 i 被捕获,需要引入中间变量,下面的代码就可以正常执行

  		static void Main(string[] args)
        {
            Task[] tasks = new Task[10];
            int[] numbers = new int[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
            for (int i = 0; i < tasks.Length; i++)
            {
                int number = numbers[i];
                tasks[i] = Task.Run(() =>
                {
                  
                    Console.WriteLine("Number:{0}", number); //这样就正常
                });

                
            }
            Console.ReadLine();
        }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#中,可以使用`Task.Factory.StartNew`方法来启动一个后台线程,并使用`Invoke`方法在UI线程上更新`Chart`控件,以避免卡顿UI。以下是一个示例代码: ```csharp using System; using System.Threading.Tasks; using System.Windows.Forms; using System.Windows.Forms.DataVisualization.Charting; class Program { static void Main(string[] args) { var chart = new Chart(); chart.Series.Add("Series1"); chart.ChartAreas.Add("ChartArea1"); chart.ChartAreas[0].AxisX.Minimum = 0; chart.ChartAreas[0].AxisX.Maximum = 10; chart.ChartAreas[0].AxisY.Minimum = 0; chart.ChartAreas[0].AxisY.Maximum = 100; var form = new Form(); form.Controls.Add(chart); form.Load += (sender, e) => { Task.Factory.StartNew(() => { var random = new Random(); var i = 0; while (true) { var value = random.Next(0, 100); chart.Invoke((Action)(() => { chart.Series["Series1"].Points.AddXY(i, value); if (chart.Series["Series1"].Points.Count > 10) { chart.ChartAreas[0].AxisX.Minimum = chart.Series["Series1"].Points[chart.Series["Series1"].Points.Count - 10].XValue; chart.ChartAreas[0].AxisX.Maximum = chart.Series["Series1"].Points[chart.Series["Series1"].Points.Count - 1].XValue; } })); Task.Delay(1000).Wait(); // 每隔1秒钟执行一次循环 i++; } }, TaskCreationOptions.LongRunning); }; Application.Run(form); } } ``` 在这个示例中,我们创建了一个`Chart`控件,并在`Form`中显示它。在`Form`的`Load`事件处理程序中,我们使用`Task.Factory.StartNew`方法来启动一个后台线程,并在其中执行循环。在循环中,我们使用`Invoke`方法来在UI线程上更新`Chart`控件。我们还检查了`Chart`中点的数量,以便在添加新点后自动调整`Chart`的`AxisX`范围,以保持最近的10个点可见。最后,我们使用`Application.Run`方法来运行`Form`并显示`Chart`控件。 请注意,在使用`Invoke`方法时,必须将更新UI的代码封装在一个`Action`委托中,以便它可以在UI线程上执行。此外,我们使用了`TaskCreationOptions.LongRunning`选项来告诉.NET运行时,该任务将运行较长时间,并可能在后台线程上使用较多的资源。最后,我们在`Task.Delay`后面调用了`.Wait()`方法来确保在执行下一次循环之前等待1秒钟,以避免在后台线程上卡顿UI。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值