背景:
我有一个控制台应用程序,它创建了用于从数据库处理数据的“任务”(称为Level1任务)。每个任务都会再次创建自己的任务来处理分配给它的数据的每个部分(Level2任务)。
每个Level2任务都有一个继续任务与之关联,并使用代码对继续任务进行 WaitAll
。
我使用的是.NET 4.0
(没有async
/await
)。
问题:
但是这样做会产生问题-结果发现,在计划所有可用的Level1任务之前,没有一个Level2任务被启动。这在任何情况下都不是最优的。
问题:
改变代码以等待原始的Level2任务及其继续任务似乎可以解决此问题。然而,我并不完全确定为什么会这样。
您有任何想法吗?
我唯一能想到的是-由于继续任务尚未开始,因此等待其完成毫无意义。但即使是这种情况,我也希望至少有一些Level2任务已经开始了。但实际上,它们从未开始。
示例:
我创建了一个演示该行为的示例控制台应用程序:
按原样运行它,您将看到它首先计划了所有任务,然后才开始从Level2任务中实际写入线路。
但是,请注释掉标记的代码块并取消注释替换,然后一切都可以按预期工作。
您能告诉我原因吗?
public class Program
{
static void Main(string[] args)
{
for (var i = 0; i < 100; i++)
{
Task.Factory.StartNew(() => SomeMethod());
//Thread.Sleep(1000);
}
Console.ReadLine();
}
private static void SomeMethod()
{
var numbers = new List<int>();
for (var i = 0; i < 10; i++)
{
numbers.Add(i);
}
var tasks = new List<Task>();
foreach (var number in numbers)
{
Console.WriteLine("Before start task");
var numberSafe = number;
/* Code to be replaced START */
var nextTask = Task.Factory.StartNew(() =>
{
Console.WriteLine("Got number: {0}", numberSafe);
})
.ContinueWith(task =>
{
Console.WriteLine("Continuation {0}", task.Id);
});
tasks.Add(nextTask);
/* Code to be replaced END */
/* Replacement START */
//var originalTask = Task.Factory.StartNew(() =>
//{
// Console.WriteLine("Got number: {0}", numberSafe);
//});
//var contTask = originalTask
// .ContinueWith(task =>
// {
// Console.WriteLine("Continuation {0}", task.Id);
// });
//tasks.Add(originalTask);
//tasks.Add(contTask);
/* Replacement END */
}
Task.WaitAll(tasks.ToArray());
}
}
ContinueWith
еҗ—пјҹиҝҳжҳҜеҸҜд»ҘдҪҝз”Ёasync/await
пјҹ - noseratio - open to workContinueWith
使用正确的任务组合和迭代模式。如果时间允许,我会将其发布为答案。 - noseratio - open to work