How not to poll for cancellation

Imagine you start a thread to perform some long-running task that you want the ability to cancel. For example, you might start that thread while your main program is waiting on user input, and then cancel that thread once the user has pressed Enter. It’s an easy thing to code up.

    private static void Main(string[] args)
    {
        bool cancelRequested = false;
        Console.WriteLine("Starting thread.");
        ThreadPool.QueueUserWorkItem((s) =>
            {
                Console.WriteLine("Thread started.");
                int counter = 0;
                while (!cancelRequested)
                {
                    // do some work here
                    ++counter;
                }
                Console.WriteLine("Thread stopped: {0}", counter);
            });
        Console.WriteLine("Press Enter to stop thread.");
        Console.ReadLine();
        cancelRequested = true;
        Console.WriteLine("Press Enter again to exit the program: ");
        Console.ReadLine();
    }

If you run that program under the debugger, you’ll find that it works just fine in Debug and in Release mode. When you press Enter, you’ll see the “Thread stopped” message as expected. However, if you run without the debugger attached, you’ll find that the thread never terminates! What’s going on?

Simply put, compiler optimization. The JIT compiler sees that nothing in the loop can modify the cancelRequested variable, so it generates code to load the value and keep it in a register. The thread never references that variable again.

Interestingly, placing a Thread.Sleep(0) in the loop disables that optimization, as does adding a lock statement. Other function calls inside the loop might also prevent that optimization, as will sufficiently complex calculations. If the exact rules for what prevents that optimization are written anywhere, I’ve been unable to find them. The C# Language Specification hints at some things, but I was unable to find any explicit language.

Absent explicit language in the specification, I’m hesitant to rely on the current behavior because it could change in the next version of the compiler or on a different platform.

There are various ways to force the compiler to examine memory at every iteration of the loop, but the options are limited when working with a Boolean. Interlocked.CompareExchange came immediately to mind, except that there isn’t an overload that takes a ref bool. I could make the variable an int, and write:

    while (Interlocked.CompareExchange(ref cancelRequested, 1, 1) == 0)

Besides being ugly, it’s not at all clear what’s going on there. I’ve written stuff like that and six months later had to come back and figure out what’s happening. If you had to go look up Interlocked.CompareExchange and puzzle out what’s happening, I think you’ll agree that this is a less than ideal solution.

Those of you with some more experience might say, “Make it volatile!” There are some problems with that. First, you can’t mark a local variable with the volatile keyword. I’d have to promote the variable to class scope. That works, sure, but it’s dissatisfying having to move a variable to an outer scope just so I can make it work the way I want. It just feels wrong.

A major problem with volatile is that it applies different semantics to variable access, but does it at the declaration site. I don’t know, when I’m writing code to access a variable, that doing so will involve acquire semantics. It would be like stepping back to the bad old days of Pascal, where passing a reference (var) parameter looked the same as passing a parameter by value. That is, given this procedure:

    procedure Frob(var fooby: Integer);

The code to call it doesn’t explicitly state that the parameter is passed by reference:

    Frob(foo);

I rather like having to specify ref in C#, and I don’t like the implicit change in memory access semantics that comes along with volatile.

At least Interlocked.CompareExchange tells you that there’s something special about that cancelRequested variable, even if the logic behind what’s happening is confusing.

More importantly, people who know a lot more than I do about C#, .NET, and multithreading in general caution against the use of volatile for several reasons, one of which is that it probably doesn’t work the way you think it works or do what you think it does. See, for example, Eric Lippert’s Atomicity, volatility and immutability are different, part three and Joe Duffy’s Sayonara volatile.

Based on those comments, volatile is not the thing I want to use when trying to write portable and reliable code. I would suggest that you, too, avoid it.

All that said, there are other ways I could solve this problem. But the simple program I showed at the start of this entry is a pretty rare case. Real programs often have multiple background tasks running, all of which are subject to cancellation either individually or as a group, and a simple Boolean variable is not a very good way to control such things.

There is a much more flexible and reliable way, which I’ll talk about in my next post.

Wear your carving glove

Saturday evening, Debra and I were over at a friend’s place. There were eight or ten of us, total, sitting or standing around, just conversing. I was also whittling on a piece of Ash, making another little dog. I don’t know if my attention lapsed (possible) or if the knife just slipped (more likely), but suddenly I was cutting into my left hand.

Surprisingly enough, it didn’t really hurt. I stared at it for a second, surprised, then stood up and grabbed a paper towel to stop the bleeding. Then to the kitchen sink to rinse it, thinking I’d just clean it a bit, bandage it up, and go back to my carving. I’ve had plenty of minor cuts, so I wasn’t terribly worried.

I only needed a brief look at the laceration while I was running it under the faucet to know that this one would need stitches. My friend handed me a wash cloth, we secured it with duct tape, and Debra drove me to the emergency room.

The second surprise (the first was that I cut myself so badly) was that the emergency room was not full at 9:00 on a Saturday night. But then, Round Rock is kind of a sleepy place. I walked up to the check-in desk. The triage nurse was safely ensconced behind a window.

Nurse: “How can I help you?”

Me (holding up left hand): “I cut myself rather badly.”

Nurse: “The duct tape didn’t fix it?”

Me (laughing): “No, but it’s holding things together for now.”

Less than a minute later, I was sitting in an exam room with a RN removing an impromptu bandage while a nursing student looked on. When she got it uncovered she said, “That’s not so bad, but recovery is gonna suck.” I had what is (apparently commonly) called a suturable laceration. It was still bleeding a bit, so she had me apply a little pressure while we waited for the nurse practitioner to come along and stitch me up.

And waited. … And waited.

I’m not sure what he used to deaden the area, but it sure hurt like heck going in. I couldn’t feel the needle going in, but it sure hurt when he pushed the contents into my hand. But within a minute my thumb felt like it’d been shot up by the dentist, and I couldn’t feel a thing when he started stitching.

The cut, by the way, is about 7 centimeters (2-3/4 inches) long, running from the base of my thumb to the center of my wrist, and almost a centimeter deep. If you’re morbidly curious, you can see the result.

Then we got to wait a even longer. Debra and I got some amusement out of all the forms they brought in, and I laughed out loud when I had to sign a document saying that I received a copy of the hospital’s no smoking policy. Oh, and they gave me a 10 mg Norco tablet and told me not to drive, and a prescription for antibiotics and more Norco. I filled the antibiotic prescription but decided against the Norco. It didn’t hurt that bad.

All in all it took about 45 minutes from the time we walked in the door until my hand was stitched up. It took another 45 minutes or an hour before they finally brought the bill, took my payment, and then came and put on the bandage before I could walk out the door. Gotta love bureaucracy.

And all because I wasn’t wearing my carving glove. The glove is Kevlar, and probably wouldn’t have completely prevented the cut, but it most likely would have made the difference between a surface scratch and a trip to the emergency room.

I’d been lax, not wearing the glove because I thought I was good enough not to need it. Only takes one slip of the blade, though, to ruin your day. I’ll be wearing the glove from now on.

How to time code

Many Stackoverflow questions amount to nothing more than, “Which of these is faster?” or “Why is this so slow?” Very often, the person posting the question will include code that outputs some timing results. More often than not, the timing code is just wrong. Sometimes fatally so.

By the way, most “Which is faster” questions are non-starters. You shouldn’t ask before you’ve done the benchmark yourself. Read on.

If you want accurate timing information, you have to do it the right way. If you do it the wrong way, your results will be at best unreliable. Fortunately, doing things the right way is pretty easy.

But before I go any further, I feel obligated to ask the most important question: Why do you care? Before you start adding code to profile small parts of your application, you need to ask yourself if it’s really that important. Or are you just wasting your time worrying about the performance of something that is already “fast enough?” I strongly suggest that you read Eric Lippert’s, Which is faster?

Now, if you really need to time your code. . .

The information below is for .NET, and the code samples are in C#. You should follow the same techniques if you’re writing in Visual Basic .NET or Managed C++, and probably any other .NET language. The general techniques are true of pretty much any other platform as well, although the specifics will be much different.

When doing benchmarks, run them against a release build with no debugger attached. In Visual Studio, be sure to select the Release build, and either press Ctrl+F5 to run, or select Debug -> Start Without Debugging. Timings gathered from a debug build or from having the debugger attached (even in a Release build) will be inaccurate. You’ll often find that there is little difference between Debug and Release builds when the debugger is attached.

Do not use DateTime.Now, DateTime.UtcNow, or anything else based on DateTime as your time source. There are two reasons for this. First, the resolution of DateTime is somewhat questionable, but probably not much better than 15 milliseconds. Secondly, the clock can change on you. I once had a bit of code take -54 minutes (yes, it completed 54 minutes before it started) to execute because it started four minutes before 2:00 AM on “Fall back” day (Daylight Saving Time autumn adjustment date) and finished six minutes later. So start time was 01:56:00 and end time was 01:02:00. You don’t control the system clock, so don’t depend on it.

Use the System.Diagnostics.Stopwatch class for all elapsed time measurements. That’s based on the Windows high performance timer, which is the most accurate interval timer you’re likely to get on a Windows box unless you have special hardware. Accept no substitutes.

With Stopwatch, timings are easy. First, add this using statement to the top of your source file:

    using System.Diagnostics;

Then, surround the code you want to time with a Stopwatch:

    Stopwatch sw = Stopwatch.StartNew(); // creates and starts the stopwatch
    //
    // put the code you want to time here
    //
    sw.Stop();  // stop the watch.
    Console.WriteLine("Elapsed time = {0} milliseconds", sw.ElapsedMilliseconds);

That’s all there is to it!

I usually like to report times in milliseconds (1/1000 second), simply because the usable range is reasonable. If I’m timing something that takes less than a millisecond to run, I need to do it many times to get a good average. A million iterations of any non-trivial loop will likely take longer than a few milliseconds. On the same note, a full day is 86,400 seconds or 86,400,000 milliseconds: a number that is still reasonably easy to work with. If I’m timing something that takes longer than a full day to run, I might decide to use seconds as my comparison.

One other nice thing about Stopwatch is that you can have many of them, each timing a discrete part of your program. For example:

    Stopwatch totalTime = Stopwatch.StartNew();

    Stopwatch pass1Time = Stopwatch.StartNew();
    DoPass1();
    pass1Time.Stop();

    Stopwatch pass2Time = Stopwatch.StartNew();
    DoPass2();
    pass2Time.Stop();

    totalTime.Stop();

You then have separate values for the total time and the time to execute each pass.

If you’ve done all of that and you still haven’t found an answer, then post a question. But include your timing code so that those of us who are willing to help you find an answer aren’t groping around in the dark. And be sure to mention that you ran in Release mode without the debugger attached.

How not to parse a file name

I’ve seen some pretty crazy code over the years, and this snippet that’s supposed to strip the extension from a Windows file name ranks right up there with the best of them.

    string GetFileNameWithoutExtension(string filename)
    {
        string result = filename;
        char[] charArray = filename.ToCharArray();
        Array.Reverse(charArray);
        string s1 = new string(charArray);
        string[] ext = s1.Split(new char[] {'.'}, 2);
        if (ext.Length > 1)
        {
            char[] charArray2 = ext[1].ToCharArray();
            Array.Reverse(charArray2);
            result = new string(charArray2);
        }
        return result;
    }

Perhaps the most important thing to understand about this code is that it’s totally unnecessary. There is a method, Path.GetFileNameWithoutExtension, which has been in the .NET Framework since version 1.1, that does exactly what the name implies.

But assuming the author didn’t know about that, why would he reverse, split, fold, spindle, and mutilate the string just to get the part after the last period?

When I was a kid, I was fascinated by that expression, “fold, spindle, or mutilate.” I knew what fold and mutilate were, but I just couldn’t figure out spindle. One day I was at the dry cleaners with my mom and a new employee was learning how to work the cash register. The experienced employee said, “…and then you put the ticket on the spindle,” and pushed the ticket onto the sharp pointy thing there on the counter. I still remember the feeling of the light going on in my head.

Anyway, back to the topic at hand.

This is the wonkiest code I’ve ever seen to do such a simple job. In a nutshell, it turns a filename, say “c:\folder\subdir\filename.ext” into “txe.emanelif\ridbus\redlof\:c”. Then, the call to string.Split splits it on the dot, giving two strings:

    "txe"
    "emanelif\ridbus\redlof\:c"

The code then takes the second of the two strings, reverses it, and that’s the result.

Convoluted in the extreme. Idiotically clever.

I guess the author had never heard of String.LastIndexOf, either. With that method, you can duplicate the code above in two lines:

    int dotPos = fileName.LastIndexOf('.');
    result = (dotPos == -1) ? fileName : fileName.SubString(0, dotPos);

Yep. That’s all his code does.

By the way, there’s a bug in his code and in mine. Given a file name like “c:\folder\subdir.001\filename_without_extension”, both will give a result of “c:\folder\subdir”.

To do it right, you have to take the slashes into account, too:

    string GetFileNameWithoutExtension(string filename)
    {
        int dotPos = filename.LastIndexOf('.');
        // if there's no dot, there's no extension
        if (dotPos == -1)
        {
            return filename;
        }
        int slashPos = filename.LastIndexOf('\\');
        // if the last slash is after the last dot, then there's no extension
        if (slashPos > dotPos)
        {
            return filename;
        }
        return filename.Substring(0, dotPos);
    }

I sure hope the guy who wrote that original code isn’t being paid to write computer programs. I pity his poor clients, living with those ticking time bombs in their code. Frightening.

Or perhaps I should hope for more people writing such code. I’ve made a lot of money over the years fixing crazy stuff like that.

The Wizard Knows Best

I suffer from the old programmer’s “anti-bloat” mentality: get rid of things that are unnecessary. After all, the file that’s never used is just taking up precious hard drive space, and is potentially confusing. There’s no need to keep it, having it clutter up the project directories and revision control system, and sitting there unused in the distribution directory. It’s just good sense to delete it. Right?

I used to complain, when creating a new C# program, that Visual Studio would barf all over my hard drive, creating a bunch of files and directories that I just didn’t want. I wanted the tool to create projects my way, not the way some goon at Microsoft decided it should be done. It took me a long time to realize that I’d be a lot better off if I just accepted the defaults. Binaries go in bin\Debug and bin\Release. The obj directory has stuff that I don’t need to care about, etc. It took a while, but after a time I realized that the Visual Studio project structure works. It’s perhaps not what I would have designed, but it works just fine.

And then I created an MVC Web application. And I thought a new Windows Forms app barfed all over my hard drive? Ha! An empty MVC application has so much crap that I’d surprised if any one person could say with certainty what all of it is for.

I created an MVC Web API project a while back. Apparently, most Web API applications also have a browser-based interface. The MVC Wizard creates the site so that browser requests go to /app/controller/action/, and API requests go to /app/api/controller/action. That seems reasonable, but I was told that my application wouldn’t have a browser interface and that all my API requests should go to /app/controller/action. That was easy enough to change, and I finished the project. Then I made a big mistake.

As I said, the MVC Wizard barfs out all kinds of unnecessary stuff: help pages, JavaScript, references to Entity Framework, service providers, and I don’t know what all else. I figured I could save myself a lot of trouble with versioning and deployment if I removed all that stuff. And it worked. My project was lean and mean, easy to deploy and with no extraneous files.

But then I was told to add some browser-accessible pages.

I won’t regale you with all the things I attempted over the day I spent trying to add all that stuff back to my project. I went home very frustrated that evening, wondering how I was going to accomplish the task. In the shower the next morning, I decided that my best course of action was to start over with a new MVC application, let the Wizard barf all over my hard drive again, and then just make the modifications I need, leaving all the extraneous crap that I have no use for. It took me approximately an hour to duplicate my application that way.

When it came time to modify another application that I had “optimized,” I didn’t even try to re-add the stuff I’d deleted. I just created a new MVC application and made my changes. 30 minutes later, I was done.

The Wizard knows best. Let it do its thing. If it creates stuff you think you don’t need, just grumble if it makes you feel better, and then get over it. Do not try to “optimize” by removing from the project those things you think you won’t ever need. If you don’t want them cluttering up your distribution directory, then modify your deployment script so that they’re not copied. But don’t remove them from the project. You’ll be sorry if you do. Trust me.

Ride 2 Recovery Texas Challenge

I encountered the participants of the Ride 2 Recovery Texas Challenge while I was out on a ride last year. I told myself that I’d join the ride this year.

The Challenge started in San Antonio on Monday, and yesterday was the leg from Austin to Ft. Hood. I signed up for the one-day ride, and took the day off from work so that I could participate.

The weather report for Wednesday was for rain, followed by a cold front. It was raining when I got up at 5:30 AM, but it was about 70 degrees outside. I don’t especially like riding in the rain, but I’ll do it if I have to.

When we started the ride at 9:00, it was about 55 degrees and still raining. The cold front had arrived. 55 degrees isn’t bad. 55 and rain is uncomfortable. 55, with rain and wind is miserable. And then the wind picked up and the temperature dropped. By the time we’d been on the road an hour, it was about 40 degrees and the wind was 15 to 20 MPH with higher gusts. I was so cold that I was shivering uncontrollably. I’ve been pretty uncomfortable on the bike before, but that was unbearable. We made a scheduled stop for a bathroom break, and the organizers gave us some extra time to warm up. We were inside where it really was warm, but I was unable to stop shivering. After about 30 minutes, they gave participants the option of continuing with the ride or taking a bus to the finish line. Considering that I couldn’t get warm and the weather hadn’t changed, I elected to cut the ride short. I’ll do a lot for the cause, and goodness knows I like a challenge, but I draw the line at hypothermia.

I can’t think of a time I’ve ever been colder. That was the most miserable bike ride I’ve ever been on, although it did have a few high points. The organizers arranged for us to ride by a number of elementary schools. The kids were all out waving American flags, cheering us on and holding out their hands. We rode by slowly and touched their hands. The kids got a real kick out of it, and many of the veterans I was riding with were touched by the gesture. Nice to see such support from the kids and also from adults who braved the cold and wet, not only near the schools but in many places along the route. We even had people get out of their cars at intersections and cheer us on as we passed.

The weather was beautiful for the Monday and Tuesday legs of the ride, and this morning was a little chilly but would not have been uncomfortable. And the forecast for the next two days is very nice. It just happened that Wednesday, the day I wanted to ride, was an unusual day. Disappointing, but that’s the way it goes. This whole month of April so far has felt more like a typical March. Dang weather, anyway.

Next year will be better, right?

Spokes ‘n Spurs ride

Yesterday was the 9th annual Spokes ‘n Spurs ride, benefiting Spirit Reins Ranch. I’ve participated in this ride for the last seven years as a volunteer, providing event communications with the Williamson County Amateur Radio Club. The ride organizers decided to use a different means of communication this year, so I was free to ride the course.

I chose to ride the 100 kilometer route, and had set an informal goal of finishing in under four hours. I didn’t want to push too hard because I’m a little out of shape. I didn’t ride over the winter, and just started getting serious about it again in March. I figured this would be a good introduction. The weather forecast called for highs around 80, and 10 to 15 MPH winds from the south, increasing to 20 or 25 in the afternoon.  I didn’t figure the wind would be too much of a problem, since the ride is primarily east/west.

Whoever laid out the course must have been a fan of M.C. Escher. Or perhaps they had the spirit of Escher lay out the course. That’s the only way they could have created a circular course that has more uphill than down.

escher1Except they did one better. They also somehow managed a constant headwind.

Joking aside, the wind was bad. It was 15 MPH to start, and the temperature was about 55 degrees. I wore my vest and arm warmers. The vest came off at 23 miles and the arm warmers at about 40. Good thing those cycling jerseys have very large pockets.

I did have a new experience on this ride: I was the leader at the very beginning. When we lined up, I was toward the front, and when we took off I somehow managed to be in the lead. For a bout the first mile. The fast people soon went by me, and I was smart enough not to try keeping up with them. That heart rate monitor is a valuable piece of equipment, provided I pay attention to what it’s telling me.

A rather large group came pedaling by at about six miles, lead by members of the Austin Flyers women’s cycling team. I let them pass, then latched on to the back, figuring I could let them pull me along for a while. That lasted until about mile 13, where we made a turn and started up a hill. Those ladies are strong. They left me and quite a few others gasping for breath as we struggled up the hill.

After that I was pretty much on my own. There were always riders nearby, and I’d chat briefly with those who passed me or whom I’d pass, but I didn’t form a group or get into a group with anybody else.

I stopped at mile 20 or so to refill my water bottles, get a few PB&J sandwiches (the benefits of an organized ride!) and peel off the vest. Then it was off on the worst stretch of the ride. From that rest stop, the course does a 17 mile loop, heading south and west to Burnet, then back to the same rest stop. There’s a lot of open space there with relatively few (compared to the rest of the course) hills, and nothing to block the wind. The wind had picked up and was about 20 MPH by then, with higher gusts. I had to work to keep from being blown over by the direct crosswind. Not fun. But I made it back to the rest stop, now at mile 40.

I’d never ridden the course on a bicycle before, but I was familiar with it from riding in the SAG wagons for several years as a volunteer. I knew that there was a series of hills from about mile 50 to about mile 55, with the first being a very short but steep (10 to 12 percent grade) little monster. I’d been dreading that stretch all day, and every time I saw my heart rate monitor reading above 80%, I’d back it off knowing that I’d need the energy later.

There was another rest stop at about mile 47. Its primary purpose, I think, is to be the midpoint rest for the 42 mile riders. I didn’t stop there, but I did notice that it was placed about 50 yards from the Oatmeal Cemetery. Coincidence?

I was right to be concerned. That first hill was tough. There were several people walking their bikes up it as I approached (riders from the 42 mile route, I think). I geared down and began ascending. When I stood up to put a little more power into the pedals, my left leg nearly locked up. I had to be very careful not to push too hard. Fortunately, the hill is short and I managed to ascend it without blowing a gasket. My heart rate did get to 86% of max, though. From there, there are several long climbs, but not nearly as steep. There’s another rest stop at mile 53 or so, but I had plenty of water and food, and I just wanted to finish the ride.

I finished the route, 60.28 miles, in 4 hours and 10 minutes. That’s an overall average of 14.5 MPH. My moving average was 15.1 MPH. I spent a total of 11 minutes at my two rest stops. It’s not my best time, but I’m okay with that. The wind was brutal, and the course did feature over 3,000 feet of climbing. Contrast that with the Waco Wild West Century, which had only 2,400 feet of climbing in 100 miles.

I’ve been impressed with the ride’s organization since the first year I volunteered for it, and I was still impressed as a participant. These people know how to put on an event. The start/finish area is well laid out, the course is well marked, the rest stops are fully stocked with food, water, and friendly people, and there is plenty of SAG support. It’s a small ride–maximum 1,000 people–but it’s really well done. And everybody I talked to on the road had nothing but good things to say about it.

If you’re an Austin area cyclist, you should seriously consider this ride next year. It’s a well organized ride on some of the most scenic roads in the area. Well worth getting up a little early and driving north to Liberty Hill.

Categories

A sample text widget

Etiam pulvinar consectetur dolor sed malesuada. Ut convallis euismod dolor nec pretium. Nunc ut tristique massa.

Nam sodales mi vitae dolor ullamcorper et vulputate enim accumsan. Morbi orci magna, tincidunt vitae molestie nec, molestie at mi. Nulla nulla lorem, suscipit in posuere in, interdum non magna.