it is all depend on the threads
let's say you have the following class
public class person
{
public int ID { get; set; }
public string Name { get; set; }
}
and here is your main Class
List<person> persons = new List<person>()
{
new person{ ID = 1,Name="Ali"}
,new person{ ID = 2,Name="Gorge"}
,new person{ ID = 3,Name="Alex"}
,new person{ ID = 4,Name="Liz"}
,new person{ ID = 5,Name="Scott"}
,new person{ ID = 6,Name="Abby"}
,new person{ ID = 7,Name="Sarah"}
};
Parallel.ForEach(persons, (p) =>
{
Console.WriteLine($"Id : {p.ID} ,Name : {p.Name}");
});
When you run this code the list items will be splits over diff threads and the code won't be running in order as you see in the following output I get the print in diff order than my original List

and here I am running the same code one more time, but I get diff results

The reason for that because of the threads, the compiler divide to number of threads and every list run the items assigned to it
the following pic show the diff threads

but when you run the following code
List<person> persons = new List<person>()
{
new person{ ID = 1,Name="Ali"}
,new person{ ID = 2,Name="Gorge"}
,new person{ ID = 3,Name="Alex"}
,new person{ ID = 4,Name="Liz"}
,new person{ ID = 5,Name="Scott"}
,new person{ ID = 6,Name="Abby"}
,new person{ ID = 7,Name="Sarah"}
};
await persons.ForEachAsync(async p => Console.WriteLine($"Id : {p.ID} ,Name : {p.Name}"));
you only get one thread as showing here

plus the data print will always be running in the same order of your list
I hope this answer explains the difference !