static void Main(string[] args)
    {
        Program p = new Program();
        p.TestAsyncInLoop();
    }
    private void TestAsyncInLoop()
    {
        var tasks = new List<Task>();
        for (int i = 0; i < 20; i++)
        {
            //tasks.Add(Task.Run(() => PrintNo(i)));
            var ii = i; 
            tasks.Add(Task.Run(() => PrintNo(ii)));
        }
        Task.WaitAll(tasks.ToArray());
    }
    private async Task PrintNo(int no)
    {
        Console.WriteLine(no);
    }
Inside the for loop, I'm calling an async method "PrintNo(int no)" passing a parameter "i" which is value type (int). When the method starts to execute, the value of "no" equals to the current value of i (which is probably 20) not the value that was sent initially in the loop! A solution I did is copying the value of "i" before sending to a new variable "ii". This solution worked fine, but can you explain why the value of "i" was not copied to the method as in sync methods? (not working code is //commented)
 
    