У меня есть пример кода для сравнения времени обработки для параллельного подхода и подхода Task. Целью этого эксперимента является понимание того, как они работают.
Итак, мои вопросы:
- Почему Parallel работала быстрее, чем Task?
- Имеют ли мои результаты, что я должен использовать Parallel вместо Task?
- Где я должен использовать Task и где Parallel?
- Какие преимущества использования Задачи по сравнению с Parallel?
-
Есть ли задача только для метода ThreadPool.QueueUserWorkItem?
public Task SomeLongOperation() { return Task.Delay(3000); } static void Main(string[] args) { Program p = new Program(); List<Task> tasks = new List<Task>(); tasks.Add(Task.Factory.StartNew(() => p.SomeLongOperation())); tasks.Add(Task.Factory.StartNew(() => p.SomeLongOperation())); var arr = tasks.ToArray(); Stopwatch sw = Stopwatch.StartNew(); Task.WaitAll(arr); Console.WriteLine("Task wait all results: " + sw.Elapsed); sw.Stop(); sw = Stopwatch.StartNew(); Parallel.Invoke(() => p.SomeLongOperation(), () => p.SomeLongOperation()); Console.WriteLine("Parallel invoke results: " + sw.Elapsed); sw.Stop(); Console.ReadKey(); }
Вот мои результаты обработки:
EDIT:
Измененный код выглядит следующим образом:
Program p = new Program();
Task[] tasks = new Task[2];
Stopwatch sw = Stopwatch.StartNew();
tasks[0] = Task.Factory.StartNew(() => p.SomeLongOperation());
tasks[1] = Task.Factory.StartNew(() => p.SomeLongOperation());
Task.WaitAll(tasks);
Console.WriteLine("Task wait all results: " + sw.Elapsed);
sw.Stop();
sw = Stopwatch.StartNew();
Parallel.Invoke(() => p.SomeLongOperation(), () => p.SomeLongOperation());
Console.WriteLine("Parallel invoke results: " + sw.Elapsed);
sw.Stop();
Мои новые результаты:
ИЗМЕНИТЬ 2: Когда я заменил код Parallel.Invoke, чтобы быть первым, и Task.WaitAll будет второй, ситуация кардинально изменилась. Теперь Parallel работает медленнее. Это заставляет меня думать о некорректности моих оценок. Я изменил код, чтобы выглядеть так:
Program p = new Program();
Task[] tasks = new Task[2];
Stopwatch sw = null;
for (int i = 0; i < 10; i++)
{
sw = Stopwatch.StartNew();
Parallel.Invoke(() => p.SomeLongOperation(), () => p.SomeLongOperation());
string res = sw.Elapsed.ToString();
Console.WriteLine("Parallel invoke results: " + res);
sw.Stop();
}
for (int i = 0; i < 10; i++)
{
sw = Stopwatch.StartNew();
tasks[0] = Task.Factory.StartNew(() => p.SomeLongOperation());
tasks[1] = Task.Factory.StartNew(() => p.SomeLongOperation());
Task.WaitAll(tasks);
string res2 = sw.Elapsed.ToString();
Console.WriteLine("Task wait all results: " + res2);
sw.Stop();
}
И вот мои новые результаты:
Теперь я могу предположить, что этот эксперимент намного яснее. Результаты почти одинаковы. Иногда Параллельная, а иногда и задача быстрее. Теперь мои вопросы:
1. Где я должен использовать Task и где Parallel?
2. Какие преимущества использования Задачи по сравнению с Parallel?
3. Задача - это просто обертка для метода ThreadPool.QueueUserWorkItem?
Любая полезная информация, которая может прояснить эти вопросы, приветствуется.