我正在玩Task函数,发现一个非常奇怪的问题,我在for循环中运行Task并将参数传递给函数(i)循环计数为100。
正如我所料,输出将是这样的。
1
2
3
4
5
但是我从这个函数得到的输出是
100个
100个
100个
我的意思是它不会改变为新的参数。有关详细信息,我上传了整个项目。
Download Sample Program that I made!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;
}
private void button1_Click(object sender, EventArgs e)
{
Task.Factory.StartNew(() => button_tast());
}
void button_tast()
{
Task[] tk =new Task[100];
for (int i = 0; i < 100; i++)
{
tk[i] = Task.Factory.StartNew(() => taskThread(i));
}
Task.WaitAll(tk);
}
void taskThread(int i){
listBox1.Items.Add(i);
}
}
}
答案 0 :(得分:8)
这是因为你是closing over the loop variable。您可以将循环重写为
for (int i = 0; i < 100; i++)
{
int taskNumber = i
tk[i] = Task.Factory.StartNew(() => taskThread(taskNumber));
}
你会没事的
答案 1 :(得分:0)
问题在于,从任务的角度来看,变量i
是全局的,并且可以以非线程安全的方式进行修改。这很容易纠正......
for (int i = 0; i < 100; i++)
{
int localCopy = i;
tk[i] = Task.Factory.StartNew(() => taskThread(localCopy));
}