.NET Programming Love, Multi-Threadedness, and CPU Usage

I do not want to ever be known as a professional software developer.

It's not because I don't enjoy programming, and certainly not because I don't appreciate the people who do love being professional developers. I do enjoy it. It's fun. I've been writing computer programs since I was drawing multi-colored circles in QuickBasic at 14 years old, and I still find it so fun that I do it as a pastime for no other reason than pure personal pleasure.

It's not because "I'm a server guy, or a hardware guy, or an architecture guy, or a network guy... and so therefore I don't need to write programs."  I know plenty of hardware, network and server architecture guys that have entire life-long careers going and don't care to write a line of code ... sometimes not even a line of script!

I don't want to be a professional developer because I'm deathly afraid that if I were forced to code for a living, it might suck all the fun out of it. It's like playing poker for a living. Sure it's fun to play poker with your buddies on a Saturday night and drink and laugh and play ... but what if you needed to play poker to earn a living? What if your performance in Texas Hold 'Em dictated how well you ate or if you made your rent for the month?  All of a sudden, Texas Hold 'Em isn't so fun any more...

You might hear me reiterate that sentiment again throughout the course of this blog, as (at this point in my life) I feel it is one of the defining sentiments of my career as an IT professional.

So, with all that said, I want to share some programming goodness that I encountered tonight, simply as an enthusiast and an amateur programmer. You are more than welcome to comment on how amateurish and unevolved as a programmer I am. I encourage it actually, as there is no better way for me to learn than by accepting constructive criticism.

I really like .NET. I love it. And what makes that very ironic is that years ago, I used to denounce languages such as Java because of its JVM nature. "Why not program against the machine itself? It would obviously be more efficient," I used to say. Well years later, here I am professing my love for .NET - a CLR language, which basically makes it the Microsoft equivalent of Java! I get the feeling that Russinovich and his ilk don't have much respect for us CLR/JVM coders because we operate in a managed sandbox environment and don't have to worry as much about things like byte-by-byte memory allocation... and god forbid we forget to de-allocate something.

But you know what? .NET gives me time to focus on solving business problems, instead of agonizing over every last little memory leak.  That's what makes .NET the perfect "Systems Engineer's" or "Systems Administrator's" language. I don't care about typecasting every last delegated sub type as an enum... and such as.  (Source: Miss South Carolina)

.NET just lets me focus on doing things and solving problems.

Tonight, I was working on a little program for myself, as opposed to something for the company where I work.  Just something that I was personally interested in.  And I had only just recently really grasped the concept of multi-threading my .NET applications. It's something that I had been struggling with for a long time... and I'm not so ashamed to admit that because there are some enterprise-grade applications that I use at work today that our company pays a lot of money for where the GUI freezes up hard for several minutes while the application downloads data and you're left staring at a non-responsive GUI... And now I know that I can do it better than that.

I guess I'll add that to list of things they should be paying me for, eh?

It's not that creating parallel threads is difficult. Least of all in .NET. You can find hundreds of examples out there on Google right now. Knowing when and where to put them in your program and how to use them effectively and design the rest of your application to work with threads effectively is the tricky part. It's a design problem, not a technical one.

It's the C# BackgroundWorker that really got me in to designing good, multi-threaded GUIs.

BackgroundWorker workerEngine = new BackgroundWorker();
workerEngine.WorkerReportsProgress = true;
workerEngine.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
workerEngine.DoWork += new DoWorkEventHandler(worker_DoWork);

And now you're executing this code in a parallel thread:

void worker_DoWork(object sender, DoWorkEventArgs e)
    // do some stuff
    // Sending "progress report" to the worker_ProgressChanged method
    ((BackgroundWorker)sender).ReportProgress(0, "I'm still working hard over here!"); 

Which can send "updates" to this method:

void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    // Sending results back to the main/GUI thread

Which can in turn interact with your GUI. You can do interesting things like populate a listbox on your GUI with updates from the background worker. See, that's one of interesting challenges for us novice coders trying to get in to multi-threaded programming... All of your GUI elements exist on one thread, and you cannot manipulate them or even get any information from them at all from another thread. So the difficulty is in creating a bridge (or a delegate, if you will,) between your threads, which we have now done with a BackgroundWorker object.

Now when you run this code, be aware that your worker thread is trying to try run as fast as he possibly can, which means he can eat up CPU time:

That's my background worker thread doing nothing but spinning in an infinite loop, causing significant CPU spikes on every core. At least the GUI remains responsive. Now let's stick a System.Threading.Thread.Sleep(100) (milliseconds) in the background thread so that perhaps he'll pace himself:

Much better! Now our background thread isn't hogging up the CPU, and our main GUI thread stays responsive and smooth throughout.

And one last thing - never put Thread.Sleep(x) anywhere on your GUI thread. It will obviously cause your GUI to be jerky and unresponsive while it's sleeping, which makes for an awful user experience.

Oh, and Merry Christmas. Hope Santa brings you what you wanted.

Comments (3) -

Well done.  You're missing the point of traditional Windows programming though.  You have more resources at your beck and call, use them!  Just because you can run a program more efficiently by changing a few trivial lines of code doesn't mean you should!  Use all the CPU you can with no regard to any other process on the machine.  While you're at it, go ahead and grab all the RAM too.  After all, small programs have needs too! Smile j/k of course.

Recursion and multi-threadedness go hand in hand as mental exercises.  Many, many people I've known just can't grasp recursion so I don't expect them to understand threading very well at all.  You either can or can't keep track of the data flow and dependencies.  Generally speaking if you can grasp one, you can understand the other.  They just know that more processes can be executed simultaneously with no understanding of why.  Some applications can take advantage of threads, some can't.  Most modern applications have old code bases which were designed for cooperative multitasking or even preemptive multitasking.  These aren't good candidates for threading rewrites in most cases just as Win XP isn't a good foundation for a large number of processors and a boatload of RAM.  Sometimes it just takes a clean sheet of paper to get the best use out of something.  Even RedHat has finally acknowledged this and no longer supports upgrades between major versions and for good reason.  Software development stagnated for a while after the .bomb so its good to see it rebounding.  

Hehe, nice... Smile

I agree with you on pretty much every point.  And there are plenty of advanced programming concepts that I would find very difficult to grasp as well, but I have fun trying.

I appreciate you stopping by to comment!

Nice article with good information.

Comments are closed