Il NET Framework 4.0 ha introdotto nuove classi per l'elaborazione parallela definite Task Parallel Library (TPL).
In questo esempio si vede come eseguire un ciclo for di 16 iterazioni che verranno eseguite in parallelo tramite l'istruzione Parallel.For.
Ogni iterazione scarica la pagina di default di questo sito tramite la classe System.Net.WebClient.
C#
using System;
using System.Threading;
using System.Diagnostics;
using System.Threading.Tasks;

namespace SgartParallelFor
{
  class Program
  {
    static void Main(string[] args)
    {
      Console.WriteLine("Main Thread={0}", Thread.CurrentThread.ManagedThreadId);

      Parallel.For(0, 16, i =>
      {
        using (System.Net.WebClient wc = new System.Net.WebClient())
        {
          Console.WriteLine(string.Format("Thread: {0} - i: {1} - Start ...", Thread.CurrentThread.ManagedThreadId, i));
          wc.Credentials = System.Net.CredentialCache.DefaultCredentials;
          string p = wc.DownloadString("http://www.sgart.it");
          Console.WriteLine(string.Format("Thread: {0} - i: {1} - String Length: {2}", Thread.CurrentThread.ManagedThreadId, i, p.Length));
        }
      });

      Console.WriteLine("\nFinished...");
      Console.ReadKey(true);
    }

  }
}
Un altro esempio con Parallel.ForEach. Partendo da un elenco di url scarica più pagine contemporaneamente.
C#
namespace SgartParallelFor
{
  class Program
  {
    static void Main(string[] args)
    {
      List<string> urls = new List<string>() {
        "http://www.sgart.it/Page/default.asp?id=29&e=443"       , 
        "http://www.sgart.it",
        "http://www.sgart.it/Page/default.asp?id=38&e=518",
        "http://www.sgart.it/Page/default.asp?id=33&e=568",
        "http://www.sgart.it/Page/default.asp?id=29&e=569",
        "http://www.sgart.it/Page/default.asp?id=29&e=545",
        "http://www.sgart.it/Page/default.asp?id=33&e=565",
        "http://www.sgart.it/Page/default.asp?id=17&e=253",
        "http://www.sgart.it/Page/default.asp?id=39&e=514",
        "http://www.sgart.it/Page/default.asp?id=23&e=539",
        "http://www.sgart.it/Page/default.asp?id=36&e=475"
      };
      Console.WriteLine("Main Thread={0}", Thread.CurrentThread.ManagedThreadId);
      Parallel.ForEach(urls, delegate(string u) {
        using (System.Net.WebClient wc = new System.Net.WebClient())
        {
          Console.WriteLine(string.Format("Thread: {0} - i: {1} - Start ...", Thread.CurrentThread.ManagedThreadId, u));
          wc.Credentials = System.Net.CredentialCache.DefaultCredentials;
          string p = wc.DownloadString(u);
          Console.WriteLine(string.Format("Thread: {0} - i: {1} - String Length: {2}", Thread.CurrentThread.ManagedThreadId, u, p.Length));
        }
      });

      Console.WriteLine("\nFinished...");
      Console.ReadKey(true);
    }

  }
}
il risultato di quest'ultimo esempio sarà simile al seguente
Main Thread=8
Thread: 8 - url: http://www.sgart.it/Page/default.asp?id=29&e=443 - Start ...
Thread: 9 - url: http://www.sgart.it/Page/default.asp?id=29&e=545 - Start ...
Thread: 10 - url: http://www.sgart.it/Page/default.asp?id=36&e=475 - Start ...
Thread: 10 - url: http://www.sgart.it/Page/default.asp?id=36&e=475 - String Length: 8401
Thread: 10 - url: http://www.sgart.it - Start ...
Thread: 9 - url: http://www.sgart.it/Page/default.asp?id=29&e=545 - String Length: 17877
Thread: 9 - url: http://www.sgart.it/Page/default.asp?id=33&e=565 - Start ...
Thread: 8 - url: http://www.sgart.it/Page/default.asp?id=29&e=443 - String Length: 19629
Thread: 8 - url: http://www.sgart.it/Page/default.asp?id=33&e=568 - Start ...
Thread: 9 - url: http://www.sgart.it/Page/default.asp?id=33&e=565 - String Length: 8893
Thread: 9 - url: http://www.sgart.it/Page/default.asp?id=17&e=253 - Start ...
Thread: 8 - url: http://www.sgart.it/Page/default.asp?id=33&e=568 - String Length: 10141
Thread: 8 - url: http://www.sgart.it/Page/default.asp?id=29&e=569 - Start ...
Thread: 9 - url: http://www.sgart.it/Page/default.asp?id=17&e=253 - String Length: 10161
Thread: 9 - url: http://www.sgart.it/Page/default.asp?id=39&e=514 - Start ...
Thread: 9 - url: http://www.sgart.it/Page/default.asp?id=39&e=514 - String Length: 10456
Thread: 9 - url: http://www.sgart.it/Page/default.asp?id=23&e=539 - Start ...
Thread: 10 - url: http://www.sgart.it - String Length: 15729
Thread: 10 - url: http://www.sgart.it/Page/default.asp?id=38&e=518 - Start ...
Thread: 9 - url: http://www.sgart.it/Page/default.asp?id=23&e=539 - String Length: 11407
Thread: 8 - url: http://www.sgart.it/Page/default.asp?id=29&e=569 - String Length: 12053
Thread: 10 - url: http://www.sgart.it/Page/default.asp?id=38&e=518 - String Length: 9157

Finished...
Attenzione, essendo l'elaborazione parallela, non è detto che l'elaborazione dei risultati avvenga secondo l'ordine definito nei for. Infatti guardando i risultati dell'esempio con Parallel.ForEach l'ordine dei risultati è differente da come sono stati definiti nella collection urls.
Potrebbe interessarti anche: