I wrote a program that works with multithreading.
The program will launch 4 threads, create a queue of 400 links and each thread will get link from the queue and send a GET request to this link.  
I created 4 threads using ThreadPool:  
for (int i = 0; i < 4; i++)
{
    ThreadPool.QueueUserWorkItem(state => worker(i));
}
The worker() function should print the worker id I gave it as an argument:  
Console.WriteLine("Worker {0} is processing item {1} with result {2}", workerId, workItem, res);  
I am expecting it to print something like that "Worker 1...., Worker 2 ..., Worker 3 ..., Worker 4 ..., Worker 1 ...".
But when I run the program it prints the same id 4 ("Worker 4"):

Full code:
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
namespace PalyGround
{
    class Program
    {
        static void Main(string[] args)
        {
            var watch = System.Diagnostics.Stopwatch.StartNew();
            RunThreadPool();
            watch.Stop();
            var elapsedMs = watch.ElapsedMilliseconds;
            Console.WriteLine("[*] Elapsed time: {0}", elapsedMs / 1000);
            Console.ReadLine();
        }
        static BlockingCollection<string> inputQueue = new BlockingCollection<string>();
        // https://stackoverflow.com/questions/6529659/wait-for-queueuserworkitem-to-complete
        private static ManualResetEvent resetEvent = new ManualResetEvent(false);
        private static void RunThreadPool()
        {
            string url = @"https://google.com";
            for (int i = 0; i < 4; i++)
            {
                ThreadPool.QueueUserWorkItem(state => worker(i));
            }
            for (int i = 0; i < 400; ++i)
            {
                //Console.WriteLine("Queueing work item {0}", url + "/" + i);
                inputQueue.Add(url + "/" + i);
                //Thread.Sleep(50);
            }
            Console.WriteLine("Stopping adding.");
            inputQueue.CompleteAdding();
            resetEvent.WaitOne();
            Console.WriteLine("Done.");
        }
        // https://stackoverflow.com/a/22689821/2153777
        static void worker(int workerId)
        {
            Console.WriteLine("Worker {0} is starting.", workerId);
            foreach (var workItem in inputQueue.GetConsumingEnumerable())
            {
                string res = "";
                //Console.WriteLine("Worker {0} is processing item {1}", workerId, workItem);
                try
                {
                    res = Get(workItem);
                }
                catch (Exception)
                {
                    res = "404";
                }
                Console.WriteLine("Worker {0} is processing item {1} with result {2}", workerId, workItem, res);
                //Thread.Sleep(100);          // Simulate work.
            }
            resetEvent.Set();
            Console.WriteLine("Worker {0} is stopping.", workerId);
        }
        // https://stackoverflow.com/a/27108442/2153777
        public static string Get(string uri)
        {
            HttpStatusCode status;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
            request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                status = response.StatusCode;
            }
            //Thread.Sleep(2000);
            return status.ToString() + "; Thread: " + Thread.CurrentThread.ManagedThreadId.ToString();
        }
    }
}
