Du verkar ha helt rätt..Långsam ThreadPool
Hejsan,
Jag sitter med ett ThreadPool-exempel från övningarna till MCTS Exam 70-536. I princip går det ut på att starta upp 4 trådar i en ThreadPool. Men så som exemplet är skrivet, när jag kör programmet, används samma tråd om och om igen såvida jag inte själv lägger in en rejäl fördröjning, på över 1 sekund, i callback'en.
Jag har spårat programflödet en smula och kan konstatera att alla fyra anropen till QueueUserWorkItem sker ögonblickligen, men sedan verkar det ta ett bra tag för trådarna att starta upp. Om jag sätter fördröjningen (se koden nedan) i varje tråd till 5 sekunder, så hinner ändå inte sista (4:e) tråden starta innan första tråden är klar. Det tar alltså mer än fem sekunder för ThreadPool att starta upp 4 parallella trådar!
Även om jag använder SetMinThreads() så att minst 5 trådar alltid skall ligga i poolen, blir resultatet detsamma.
Min tolkning, just nu, är att denna minimigräns inte gäller förrän man faktiskt, i praktiken, har haft 5 trådar igång samtidigt. (och att det inte ligger 5 färdigskapade trådar i poolen innan dess) Jag kan alltså vänta mig att innan applikationen har behövt 5 trådar så kan det hel plötsligt krävas över en sekunds väntan när en ny tråd behöver startas upp. Och rent generellt gäller då, med ThreadPool att så fort jag behöver använda en tråd mer än det antal jag någonsin tidigare behövt, så måste jag räkna med denna dryga sekunds väntan på att tråden skall komma igång.
Jag har inte hittat något om detta i övningsboken. Är jag på rätt spår eller?
----------
Exempelkod
static void Main(string[] args)
{
WaitCallback callback = new WaitCallback(ShowMyText);
ThreadPool.QueueUserWorkItem(callback, "Hello");
ThreadPool.QueueUserWorkItem(callback, "Hi");
ThreadPool.QueueUserWorkItem(callback, "Heya");
ThreadPool.QueueUserWorkItem(callback, "Goodbye");
Console.Read();
}
static void ShowMyText(object state)
{
string myText = (string)state;
Thread.Sleep(5000); //Så att denna tråd inte blir färdig innan nästa hinner starta!!!
Console.WriteLine("Thread: {0} - {1}", Thread.CurrentThread.ManagedThreadId, myText);
}Sv: Långsam ThreadPool
om man modifierar ditt exempel lite:
static void Main(string[] args)
{
WaitCallback callback = new WaitCallback(ShowMyText);
//maxxa ut threadpoolen så att minthreads fylls
//här kommer det ta tid innan alla trådar skapats
ThreadPool.QueueUserWorkItem(callback, "Hello");
ThreadPool.QueueUserWorkItem(callback, "Hi");
ThreadPool.QueueUserWorkItem(callback, "Heya");
ThreadPool.QueueUserWorkItem(callback, "Goodbye");
ThreadPool.QueueUserWorkItem(callback, "Hello");
ThreadPool.QueueUserWorkItem(callback, "Hi");
ThreadPool.QueueUserWorkItem(callback, "Heya");
ThreadPool.QueueUserWorkItem(callback, "Goodbye");
//vänta tills alla trådar kört klart
Console.ReadLine();
//fyll threadpoolen igen
//följande jobb kommer att utföras instant , med olika trådar eftersom trådarna redan finns...
ThreadPool.QueueUserWorkItem(callback, "Hello");
ThreadPool.QueueUserWorkItem(callback, "Hi");
ThreadPool.QueueUserWorkItem(callback, "Heya");
ThreadPool.QueueUserWorkItem(callback, "Goodbye");
ThreadPool.QueueUserWorkItem(callback, "Hello");
Console.ReadLine();
}
static void ShowMyText(object state)
{
string myText = (string)state;
//gör writeline innan sleep, så ser man direkt när tråden börjar köra
Console.WriteLine("Thread: {0} - {1}", Thread.CurrentThread.ManagedThreadId, myText);
Thread.Sleep(5000); //Så att denna tråd inte blir färdig innan nästa hinner starta!!!
}