I need to develop an app that is using multithreading.
Basicly, I have a DataTable that contains around 200k rows.
From each row, I need to take a field, compare it to a webpage,
and then remove it from the datatable.
The thing is, the server serving those pages has a limit on concurrent requests.
so at max I can ask for 3 pages at the same time.
I want to do this by using the threadpool,
I even managed building a simple app that does that ( locks the datatable )
but I couldn’t limit the concurrent threads ( even with SetMaxThreads ) it seems like it just ignored the limit.
does anyone have something ready made that does something similar ?
I would love to see.
i have tried using semaphores, but got into problems:
static SemaphoreSlim _sem = new SemaphoreSlim(3); // Capacity of 3
static List<string> records = new List<string>();
static void Main()
{
records.Add("aaa");
records.Add("bbb");
records.Add("ccc");
records.Add("ddd");
records.Add("eee");
records.Add("fff");
records.Add("ggg");
records.Add("iii");
records.Add("jjj");
for (int i = 0; i < records.Count; i++ )
{
new Thread(ThreadJob).Start(records[i]);
}
Console.WriteLine(records.Count);
Console.ReadLine();
}
static void ThreadJob(object id)
{
Console.WriteLine(id + " wants to enter");
_sem.Wait();
Console.WriteLine(id + " is in!"); // Only three threads
//Thread.Sleep(1000 * (int)id); // can be here at
Console.WriteLine(id + " is leaving"); // a time.
lock (records)
{
records.Remove((string)id);
}
_sem.Release();
}
this runs quite nicely, the only problem is,
Console.WriteLine(records.count);
returns diffrent results.
even due i understand that it happens since not all the threads have finished ( an i a m calling the records.count before all records have been removed) i couldnt find how to wait for all to finish.
To wait for multiple threads to finish, you can use multiple
EventWaitHandle‘s and then callWaitHandle.WaitAllto block the main thread until all events are signalled:Since most of these threads would end up suspended most of the time, it would be better to use
ThreadPoolin this case, so you can replacenew Threadwith:When you are done with the events, don’t forget to Dispose them:
[Edit]
To put it all in one place, here is what your example code should look like:
(note that I’ve used
Semaphoreinstead ofSemaphoreSlimbecause I don’t have .NET 4 on this machine and I wanted to test the code before updating the answer)