static void Main(string[] args)
{
    var repo = new StudentRepository();
    List<Student> students = new List<Student>();
    var myLock = new object();
    //version 1-----------------------------------------------
    for (int i = 1; i <= 20; i++)
    {
        var stud = repo.GetStudentById(i);
        students.Add(stud);
    }
    //version 2-----------------------------------------------
    var ids = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
    Parallel.ForEach(ids, id =>
    {
        var stud = repo.GetStudentById(id);
        lock (myLock)
        {
            students.Add(stud);
        }
    });
    //version 3------------------------------------------------ -
    List<Task> tasks = new List<Task>();
    for (int i = 1; i <= 20; i++)
    {
        tasks.Add(Task.Factory.StartNew(() =>
        {
            var stud = repo.GetStudentById(i);
            lock (myLock)
            {
                students.Add(stud);
            }
        }));
    }
    Task.WaitAll(tasks.ToArray());
    students.ForEach(s => Console.WriteLine(s.Id + "---" + s.Name));
    Console.ReadLine();
}
Output With version 1

Output With version 2

- Is there any difference between version 1 and version 2 (performance wise)?
- While version 2 gives proper results version 3 stores null in student list(i.e. students). What wrong I am doing here?
 
    