0

The code is to generate random numbers in 100 files numbered from 0..99.

What I couldn't get was why this code ended up creating a file called 100.txt and I even got an exception saying that 100.txt was being written by another process.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RandomNumbersFileGenerator
{
    class Program
    {
        static Random Random = new Random();

        static void Main(string[] args)
        {
            List<Task> tasks = new List<Task>();
            for(int fileNumber = 0; fileNumber < 100; ++fileNumber)
            {
                tasks.Add(Task.Run(()=>GenerateFileWithRandomNumbers(Path.Combine($"c:\\FilesWithRandomNumbers\\{fileNumber}.txt"), 10000000)));
            }

            Task.WaitAll(tasks.ToArray());
        }

        static void GenerateFileWithRandomNumbers(string path, int numberOfNumbers)
        {
            List<string> listOfNumbers = new List<string>();
            for(;numberOfNumbers > 0; --numberOfNumbers)
            {
                listOfNumbers.Add(Random.Next().ToString());
            }

            File.WriteAllLines(path, listOfNumbers);
        }
    }
}
user3265356
  • 49
  • 1
  • 5
  • 1
    possible duplicate of [Why is it bad to use an iteration variable in a lambda expression](http://stackoverflow.com/questions/227820/why-is-it-bad-to-use-an-iteration-variable-in-a-lambda-expression) – sstan Aug 22 '15 at 23:32
  • @sstan It is an old document and things have changed since c# 5.0. The first example(*foreach*) will work now – Eser Aug 22 '15 at 23:34
  • @Eser: I changed my mind. I deleted my comment. It can cause more harm than good. Thanks for pointing it out. – sstan Aug 22 '15 at 23:40

1 Answers1

2

It is related to closures and captured variables. Change

for(int fileNumber = 0; fileNumber < 100; ++fileNumber)
{
      tasks.Add(Task.Run(()=>GenerateFileWithRandomNumbers(Path.Combine($"c:\\FilesWithRandomNumbers\\{fileNumber}.txt"), 10000000)));
}

To

for(int fileNumber = 0; fileNumber < 100; ++fileNumber)
{
      int tmp = fileNumber;       
      tasks.Add(Task.Run(()=>GenerateFileWithRandomNumbers(Path.Combine($"c:\\FilesWithRandomNumbers\\{tmp}.txt"), 10000000)));
}

See also http://csharpindepth.com/articles/chapter5/closures.aspx

Eser
  • 12,346
  • 1
  • 22
  • 32