Я думаю, что создание очереди из поставленных в очередь элементов как-то не совсем правильно, так как насчет того, чтобы заставить WorkItems снова ставить себя в очередь после того, как они закончили?
Ваш метод Start может поставить в очередь, скажем, 3 раза элементы MaxThreads (75 в вашем примере), а затем ваш метод Process будет поставлен в очередь, когда он будет завершен. Таким образом, ваш метод Start быстро возвращается, но запускает несколько рабочих элементов, которые, как я уже сказал, запускаются сами:
public class Scraper
{
private int MaxUserID { get; set; }
private int MaxThreads { get; set; }
private int currentUserID;
private bool Running { get; set; }
private Parser StatsParser = new Parser();
private int Multiplier { get; set; }
public Scraper()
: this(0, Int32.MaxValue, 25)
{
}
public Scraper(int currentUserID, int maxUserID, int maxThreads)
{
this.currentUserID = currentUserID;
this.MaxUserID = maxUserID;
this.MaxThreads = maxThreads;
this.Running = false;
ThreadPool.SetMaxThreads(maxThreads, maxThreads);
Multiplier = 3;
}
public void Start()
{
Running = true;
for (int i = 0; i < MaxThreads * Multiplier; i++)
{
ThreadPool.QueueUserWorkItem(Process);
}
}
public void Stop()
{
Running = false;
}
public void Process(object state)
{
if (Running == false)
{
return;
}
if (currentUserID < MaxUserID)
{
Interlocked.Increment(ref currentUserID);
//Parse stats for currentUserID
ThreadPool.QueueUserWorkItem(Process);
}
else
{ Running = false; }
}
}
Я уверен, что флаг безопасности должен быть установлен с использованием Interlocked для безопасности. Я сделал множитель в свойстве, которое можно было передать конструктору - я вполне уверен, что его можно откорректировать, чтобы настроить производительность в зависимости от того, сколько времени потребуется для анализа этой статистики.