Проблемы с правильной реализацией цикла Parallel.ForΕach и продолжением другой работы в это время.C#

Место общения программистов C#
Ответить
Anonymous
 Проблемы с правильной реализацией цикла Parallel.ForΕach и продолжением другой работы в это время.

Сообщение Anonymous »

Мы используем .Net Framework 4.8.2. Для какой-то части приложения я хочу параллельно выполнять множество длительных процессов, связанных с процессором и вводом-выводом (показано Thread.Sleep()). Вот почему я использую цикл Parallel.ForΕach. Эти результаты не нужны в течение некоторого времени. Вот почему я хочу продолжить другую работу и «приостановить» эту задачу задач (так сказать) в другом потоке, тогда как каждый Parallel.ForΕach выполняется снова в другом потоке. Вот почему я возвращаю Parallel.ForΕach, инкапсулированный в оператор Task.Run(). Код выглядит следующим образом:

Код: Выделить всё

internal class Program
{
static async Task Main(string[] args)
{
Console.WriteLine($"Before ParallelForeach on thread: {Environment.CurrentManagedThreadId}"); //Main debug 1
await TaskContainingParallelForeach();
Console.WriteLine($"After  ParallelForeach on thread: {Environment.CurrentManagedThreadId}"); //Main debug 2
int counter = 0;
while (counter < 7)
{
Console.WriteLine($"{counter}. one second gone on thread:  {Environment.CurrentManagedThreadId} at {DateTimeOffset.Now.ToUnixTimeMilliseconds()}");
Thread.Sleep(1000);
counter++;
}

Console.ReadKey();
}

public static Task TaskContainingParallelForeach()
{
return Task.Run(() =>
{
Console.WriteLine($"Inside ParallelForeach on thread: {Environment.CurrentManagedThreadId}");
int[] numbers = { 1, 3, 2 };

Parallel.ForEach(numbers, (num) =>
{
Console.WriteLine($"{num} is running on thread: {Environment.CurrentManagedThreadId}");
Thread.Sleep(num * 1000);
Console.WriteLine($"{num}    stopped on thread: {Environment.CurrentManagedThreadId}        at {DateTimeOffset.Now.ToUnixTimeMilliseconds()}");
});
});
}}
Это дает мне следующий результат:

Код: Выделить всё

Console Output without await:
Before TaskContainingParallelForeach on thread: 1
Inside TaskContainingParallelForeach on thread: 3  // why is -below- first done all the work from the ParallelForeach?
1 is running on thread: 3
3 is running on thread: 4
2 is running on thread: 6
1    stopped on thread: 3        at 1734365740995
2    stopped on thread: 6        at 1734365741996
3    stopped on thread: 4        at 1734365742996
After  TaskContainingParallelForeach on thread: 3 // why is it the thread with id 3 here - expected was 1
0. one second gone on thread:  3 at 1734365742996
1. one second gone on thread:  3 at 1734365743997
2. one second gone on thread:  3 at 1734365745008
3. one second gone on thread:  3 at 1734365746023
4. one second gone on thread:  3 at 1734365747035
5. one second gone on thread:  3 at 1734365748047
6. one second gone on thread:  3 at 1734365749061
Параллельный.ForEach запускается, и только после его завершения запускается цикл while. Оператор await должен вести себя следующим образом: (Исходная документация) Оператор await приостанавливает вычисление включающего асинхронного метода до выполнения асинхронной операции. Мой асинхронный метод — TaskContainingParallelForeach. Или нет?
И почему идентификатор потока для After TaskContainingParallelForeach в потоке 3, а не 1? И почему цикл while не выполняется в потоке 1?
Однако удаление оператора await из await TaskContainingParallelForeach(); дает желаемый результат:

Код: Выделить всё

Console output without await:
Before TaskContainingParallelForeach on thread: 1
After  TaskContainingParallelForeach on thread: 1
Inside TaskContainingParallelForeach on thread: 3
1 is running on thread: 3
3 is running on thread: 4
2 is running on thread: 5
0. one second gone on thread:  1 at 1734364096009
1    stopped on thread: 3        at 1734364097021
1. one second gone on thread:  1 at 1734364097036
2    stopped on thread: 5        at 1734364098027
2. one second gone on thread:  1 at 1734364098043
3    stopped on thread: 4        at 1734364099022
3. one second gone on thread:  1 at 1734364099053
4. one second gone on thread:  1 at 1734364100064
5. one second gone on thread:  1 at 1734364101077
6.  one second gone on thread:  1 at 1734364102078
Выглядит великолепно!
  • все работает Цикл Parallel.Foreach запущен
  • Тем временем цикл while начал свою работу
  • Цикл while находится в ожидаемом потоке 1.
Но я думаю, что это не то, что ждет с помощью Task.Run() и Parallel.Foreach следует использовать вместе. Как я могу проверить этот код?
Заранее спасибо!

Подробнее здесь: https://stackoverflow.com/questions/792 ... her-work-i
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»