фон:Task.WaitAll() при выполнении задачи только задерживает выполнение исходной задачи?
У меня есть консольное приложение, которое создает Tasks
для обработки данных из БДА (давайте называть их LEVEL1 задачами). Каждая из задач снова создает свои собственные Задачи для обработки каждой части данных, которые ей были назначены (задачи уровня 2).
Каждая из задач Level2 имеет связанную с ним задачу продолжения и код, используемый для выполнения WaitAll в задачах продолжения, прежде чем двигаться дальше.
Я на .NET 4.0
(нет асинхронной/ждать)
Выпуск:
Это создало проблему, хотя - оказалось, что если сделано таким образом, ни одна из задач LEVEL2 не начато до все запланированные задачи Level1 были запланированы. Это не оптимально.
Вопрос:
Это, кажется, фиксируется с изменением кода ждать как исходной задачи Level2 и продолжение задачи. Однако я не совсем уверен, почему это так?
Есть ли у вас идеи?
Единственное, что я мог придумать, это то, что, поскольку задача продолжения не началась, нет смысла ждать ее завершения? Но даже если бы это было так, я ожидал бы, по крайней мере, НЕКОТОРЫХ из задач Level2, которые нужно было запустить. Которые они никогда не делали.
Пример:
Я создал образец консольного приложения, которые продемонстрировали именно такое поведение:
Run это как есть, и вы увидите, что это планирование всех задач, во-первых, и только потом вы начинаете получать фактические сценарии из задач 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
@Noseratio - это .NET 4.0 - нет async/await –
Вы все еще можете использовать его для .NET 4.0, если используете VS2012 +: http://stackoverflow.com/tags/async-await/info – Noseratio