Parallel.For with vs without async/await - C#

Shervan360 1,661 Reputation points
2023-03-07T18:42:58.86+00:00

Hello,

Could you please see the snippet code and tell me what is the differences between Parallel.For with vs without async/await?

Why is the result that every end log of a loop uses the same thread and task as the start log? (First snippet code)

In the second snippet code, we can see that tasks no longer exist—there are only threads—and here previous threads are

reused. Why?

Why does the For method of the Parallel class is completed without waiting for the delay? (In the second snippet code)

Could you kindly explain with details? I'm confused!


class Program
{
    static void Main(string[] args)
    {
        ParallelFor();
    }
    public static void ParallelFor()
    {
        ParallelLoopResult result =
            Parallel.For(0, 10, i =>
            {
                Log($"S {i}");
                Task.Delay(10).Wait();
                Log($"E {i}");
            });
        Console.WriteLine($"Is completed: {result.IsCompleted}");
    }
    public static void Log(string prefix)
    {
        Console.WriteLine($"{prefix}, task: {Task.CurrentId}, " +
            $"thread: {Thread.CurrentThread.ManagedThreadId}");
    }
}

PF02

PF01

class Program
{
    static void Main(string[] args)
    {
        ParallelFor();
    }
    public static void ParallelFor()
    {
        ParallelLoopResult result =
            Parallel.For(0, 10, async i =>
            {
                Log($"S {i}");
                await Task.Delay(10);
                Log($"E {i}");
            });
        Console.WriteLine($"Is completed: {result.IsCompleted}");
    }
    public static void Log(string prefix)
    {
        Console.WriteLine($"{prefix}, task: {Task.CurrentId}, " +
            $"thread: {Thread.CurrentThread.ManagedThreadId}");
    }
}
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
11,497 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Minxin Yu 13,501 Reputation points Microsoft External Staff
    2023-03-08T08:59:35.67+00:00

    Hi, Shervan360

    Update:
    The problem you are having is similar to this Why Task.CurrentId becomes NULL after Task.Delay:

    Only Delegate tasks have CurrentId set. So the ID you're seeing is not the ID of the task returned from SomeMethod (you can verify this by checking the ID on the task returned from SomeMethod). It's the ID of just the first block of synchronous code. The rest of the blocks (the continuations) are run directly on the thread pool and are not wrapped in tasks, so there is no CurrentId for them.

    Best regards,

    Minxin Yu


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.