Not that I'm not appreciative of the powers of multithreading or ThreadPool
, but I'm scared I broke something since I'm getting a roughly 20x speed increase (2-3s down from over a minute) with a relatively naive usage of ThreadPool
. So I submit my code here to be torn apart by people far wiser than I.
Am I doing something wrong here, or is this just a far better candidate for multithreading than I ever hoped? (Yes, this function is an entire thread: like I said, this used to take over a minute to run)
EDIT: To answer my own question, no, this is broken: It seems to be running multiple times, but over the same trigger. Is this because of the way lambda are handled?
private static void CompileEverything()
{
try
{
// maintain the state of our systray icon
object iconLock = new object();
bool iconIsOut = true;
// keep a count of how many threads are still running
object runCountLock = new object();
int threadRunning = 0;
foreach (World w in Worlds)
{
foreach (Trigger t in w.Triggers)
{
lock (runCountLock)
{
threadRunning++;
}
ThreadPool.QueueUserWorkItem(o =>
{
// [snip]: Do some work involving compiling code already in memory with CSharpCodeProvider
// provide some pretty feedback
lock (iconLock)
{
if (iconIsOut)
notifyIcon.Icon = Properties.Resources.Icon16in;
else
notifyIcon.Icon = Properties.Resources.Icon16out;
iconIsOut = !iconIsOut;
}
lock (runCountLock)
{
threadRunning--;
}
});
}
}
// wait for all the threads to finish up
while (true)
{
lock (runCountLock)
{
if (threadRunning == 0)
break;
}
}
// set the notification icon to our default icon.
notifyIcon.Icon = Properties.Resources.Icon16;
}
// we're going down before we finished starting...
// oh well, be nice about it.
catch (ThreadAbortException) { }
}