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();
}
}
}