c# Task do not work without sleep between them

c#, multithreading, task

Solution

Look at your code:

int j = 0;
foreach (string f in file)
{  
    result[j] = new Task<bool>(() => ftp.UploadFtp(f, "C:\\Prova\\" + f + ".txt", j));
    result[j].Start();
    j++;
}

The lambda expression uses the current value of `j` whenever it's executed. So if the task starts after the `j` is incremented, you'll miss the value you intended.

In C# 4, you have the same problem with `f` - but this has been fixed in C# 5. See Eric Lippert's blog post "Closing over the loop variable considered harmful" for more details.

The smallest fix is trivial:

int j = 0;
foreach (string f in file)
{  
    int copyJ = j;
    string copyF = f;
    result[j] = new Task<bool>(
         () => ftp.UploadFtp(copyF, "C:\\Prova\\" + copyF + ".txt", copyJ));
    result[j].Start();
    j++;
}

Now nothing will change `copyJ` and `copyF` - you'll get a separate variable being captured in each iteration of the loop. In C# 5, you don't need `copyF`, and can just use `f` instead.

... but I'd also suggest using `Task.Factory.StartNew()`, (or `Task.Run` in .NET 4.5) or just `Parallel.For`.

Problem

I'm using Task in c# to send file via FTP in multithread. here is my function (file is a list of strings) ``` Task<bool>[] result = new Task<bool>[file.Count]; int j = 0; foreach (string f in file) { result[j] = new Task<bool>(() => ftp.UploadFtp(f, "C:\\Prova\\" + f + ".txt", j)); result[j].Start(); j++; //System.Threading.Thread.Sleep(50); } Task.WaitAll(result, 10000); ``` and the function to upload files ``` public static bool UploadFtp(string uploadFileName, string localFileName, int i) { FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://127.0.0.1/" + uploadFileName + ".txt"); //settare il percorso per il file da uplodare //FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://desk.txt.it/"); request.Method = WebRequestMethods.Ftp.UploadFile; request.Credentials = new NetworkCredential("ftp_admin", ""); //request.Credentials = new NetworkCredential("avio", "avio_txt"); try { Console.WriteLine(uploadFileName); Console.WriteLine(i); StreamReader sourceStream = new StreamReader(localFileName); byte[] fileContents = File.ReadAllBytes(localFileName); sourceStream.Close(); request.ContentLength = fileContents.Length; Stream requestStream = request.GetRequestStream(); requestStream.Write(fileContents, 0, fileContents.Length); requestStream.Close(); FtpWebResponse response = (FtpWebResponse)request.GetResponse(); //MessageBox.Show("Upload File Complete, status {0}", response.StatusDescription); response.Close(); return true; } catch (Exception e) { return false; } } ``` in this way the program try always to save the last file of the list, but if I add a Sleep(50) it uploads the files correctly. it seems that the program starts 4 task doing the same job (saving the last file) only if I do not use sleep, but I do not understand why and I don't know how to solve the problem. Can someone help me? thank you

Original source