【发布时间】:2017-12-31 08:17:29
【问题描述】:
我将重新表述这个问题。这是我想做的简化代码。 标签 将是动态的,并且必须在函数中传递。函数startCount() 会做更多的事情,我想把每一个都删掉以节省时间。代码工作正常(现在计算并更改值)。
当所有任务完成后,我还需要执行其他功能。
我在startCount()函数中取出了多余的Task。
至于其他示例,我没有使用 await 并且在 startCount() 中删除了 Task 现在程序冻结了。
private void Form1_Load(object sender, EventArgs e)
{
strCounter.Add("66"); //Simulate reading file
strCounter.Add("69");
labels = new Label[strCounter.Count]; //Create the Array of Labels
for (int i = 0; i < strCounter.Count; i++)
{
labels[i] = new Label(); //Create label and add it to Form
labels[i].Size = new Size(30, 15);
labels[i].Location = new Point(10, 50 + (i * 20));
labels[i].Text = strCounter[i];
this.Controls.Add(labels[i]);
}
}
private void button1_Click(object sender, EventArgs e)
{
List<Task> tasks = new List<Task>(); //Create List of Tasks
for (int i = 0; i < strCounter.Count; i++)
{
int ii = i;
Task LastTask = new Task(() => startCount(i.ToString(), labels[ii]));
tasks.Add(LastTask);
tasks[i].ConfigureAwait(false);
tasks[i].Start();
}
// This line will cause the entire program to freeze.
// If i comment out, the program works fine.
Task.WaitAll(tasks.ToArray());
MessageBox.Show("Should be After");
}
private void startCount(string strCount, Label lbl)
{
for (int i = 0; i < 100; i++)
{
int count = int.Parse(lbl.Text) + 1; //Add 1
writeLabelBox(lbl, count.ToString()); //Use Invoke function
Thread.Sleep(20);
}
}
public void writeLabelBox(Label l, string strA)
{
this.Invoke((MethodInvoker)delegate()
{
l.Text = strA;
});
}
【问题讨论】:
-
可能所有任务都完成了?
-
这太可怕了,你无缘无故地创建任务。你会饿死线程池。
-
您不需要做
new Task或Task.Start()。这些是您不使用的高级功能所必需的,并且会使事情复杂化。请改用Task.Run()。还有@ErikPhilips 所说的——你在太细粒度的水平上并行化事情,它会变得更慢。因此,如果它是一款真正的应用,请重新考虑您的策略。 -
你的代码有很多问题,但主要是你已经将你真正想要等待的任务包装在一个立即完成的不同任务中,因为不同的任务是无非是创建您真正想要等待的任务(当然,这需要很少的时间)。查看 Stack Overflow 上数千个或更多类似问题的标记重复项,我们已经回答了这些问题。
-
我真的将代码简化为它真正要做的事情。该标签是众多标签中的一部分,并且不希望为该问题添加额外代码。是的,我确实想解决这个问题。该线程将为 UI 提供更新时间,如果我注释掉 Task.WaitAll(tasks.ToArray());.,它可以正常工作