How to Read a Tech Book

johnnymnomonic

My efforts to write about learning Silverlight in Seven Days are filled with omissions and gaps.  While each Silverlight "day" really does constitute one day’s worth of studying, they haven’t been contiguous days.  One large gap is due to a trip I had to make to Washington D.C. to settle personal affairs.  Others were job related since, like most of you, I have to maintain my day job even as I’m expending effort to learn new technology in my off time — which, however, will eventually feed back into my day job.  Which invites the obvious question of whether learning technology is really work time or private time.  I tend to think of it as private time, since I enjoy it immensely and grow personally by doing it.  All the same — and I believe this is not the case in most IT shops — my day job is actually forward looking about this sort of thing, and allows me to spend part of my day learning all the new acronyms coming out of Redmond — in some sense paying me to do something I love.  But an equally valid way of looking at it is that I am working to keep my IT shop informed about the best solutions for its upcoming projects, and the reward for the investment of time and energy I make in learning these technologies are ultimately reaped by my company.  I am, in effect, investing my company’s time wisely.

Should we choose to look at the matter in this way, then it is important that the time spent on learning technology be used optimally.  This is hampered by the fact that information about things like WCF, WPF, WF (the initial "W" is typically truncated, I assume, because it evokes notions of profession wrestling) and Silverlight are poorly disseminated.  Half of the effort spent on learning new tech involves tracking down the proper resources, weeding out the unhelpful books that misstate what they can offer and the ones that are just poorly written or misinformed, and finding the correct location for the online resources — including source code — that one needs.  Scott Galloway has a great post about this problem over on his blog: http://www.mostlylucid.net/.

The other half is spent actually engorging all the information that is available.  There is a scene from Johnny Mnemonic, that peculiar 1995 Keanu Reeves sci-fi vehicle, in which Keanu uploads 300 megabytes of data into his cerebral cortex.  In order to prepare for it, he puts a bite guard in his mouth, clamps down and, with evident consternation on his face, yells out "hit me."  This is how I feel whenever I prepare myself to sit down with a tech book.

A tech book is not a friendly beast.  You cannot curl up with it in bed.  You never giggle over a clever turn of phrase and beg your partner to allow you to read her a passage aloud.  Instead, it is a big heap of bound paper, generally printed in large type in an apparent attempt to make it seem weightier than it has any right to be, which you have to plow through in a Sisyphusian effort to reach the end.  In truth, no one ever gets to the end of one of these things because we all get bogged down in the details.  This is natural enough, because the presentation is typically all about the details after the initial chapter, and the initial chapter tends to alternate between vagueness and hello world samples to the point that it just can’t be taken very seriously.  But then we get lost in the details.  There is so much we don’t understand in reading through these tech books that we become frantic over the thought that we might be missing something important — the key that unlocks all the material we are trying to absorb.  The reading process becomes slower and more onerous until finally external affairs draw us back into the life-world or we throw our tech book to the wall where, with luck, it shatters into a million pieces and we never have to pick up reading again where we left off.

Scott Hanselman touches on this point in his post: Books: We Need More So What, Now What, And What For And Less Just What, though it might just as easily have been titled, "Why Tech Books Suck".  The essential problem with tech books is that they never work out the inherent paradox of all learning: one cannot learn the whole without understanding the parts; one cannot know the parts without understanding the whole.  In contemporary exegetics, this known as the hermeneutic circle.

Aristotle says in his Poetics that tragedies such as Oedipus Rex and Electra are higher and more philosophical than historical works because they aspire to truth, whereas histories merely offer details.  I think it is this desire to know the "truth" of a technology — its purpose, its potential, it’s meaning — from a medium so poorly suited to this task, the tech book, that typically leaves us feeling so frustrated and so drained.  We get bogged down in details because tech authors get bogged down in details, and it is the exceptional writer who knows how to navigate the hermeneutic circle in order to provide us with a usable tech book — the criterion for usability, in this case, being merely not making us want to throw it across the room.

The quality of tech books is out of our control, however, so we must turn to the quality of reading tech books.  Here are my suggestions for how to get the most out of a tech book, so that as little time is wasted on them as possible:

1. Read Online — I use Safari Books Online for my tech education, as well as MSDN and various tech blogs.  This tends to make my eyes bleed, but it has the distinct advantage of not lulling me into the illusion that tech books are like other books.  Once I start treating tech books like other books, I find that I fall into the habits I’ve acquired for reading fiction and even most non-fiction.  I look for a plot and my mind tries to work itself towards a narrative climax that never actually transpires.  Tech books don’t have plots.  They just are.  If you rip out the chapters and put them together in a different sequence, it generally doesn’t matter.  Tech books are heaps, not paths.  Reading online helps me to avoid this confusion — though it obviously isn’t for everyone.

2. Plan to Re-read — if you set out on a new book knowing that you will re-read it, then you won’t get so bogged down in the details.  You can always go back and pick up what you missed later.  I generally read a tech book three times.  The first time I just skim through the chapter headings so I know what the book is going to cover and what I feel confident about skipping entirely.  This can be done in a few minutes.  On the second read, I just skim the whole book.  I don’t try to do any coding exercises.  I just get a good grasp of the principles involved, and the various materials I will need to understand.  The goal is simply to get to the end of the book, not to understand it in its entirety.  This can be done in a few hours.  The third read is used to go back and pick up the important stuff.  From the second read, I know that there are things I don’t understand, and hopefully I will have formed an opinion of what is important in the book and what is drivel.  In the third read, if a third read is even necessary, I pick up the important bits.

3. Give Yourself Permission to Skip — The fear of missing something important is a paralyzing fear.  You have to give yourself permission to skip things when you are reading a tech book.  Remember, a lot of the things in a tech book are just filler.  The author felt he had to push something in that is actually irrelevant, or the publisher has established a page count for him that he must fulfill.  Not everything in a tech book is important.  Marshall McLuhan developed a habit of reading only the right hand pages of any non-fiction book (he would read a non-fiction book in its entirety, however).  The way he explained it, a lot of non-fiction is just filler, and by his estimation, only 10% or so of any non-fiction book was actually worth knowing — and that was if it was a good book.  An intelligent person can fill in the gaps as he goes along.  More importantly, the way your mind fills in these interstitial gaps actually helps it to retain information better.  The mind learns not by simply replicating what it finds in a book, like some copying machine, but rather by trying to reconstruct and build things in the imagination.  In rhetoric, this is sometimes called an enthememe, or a logical argument with gaps.  The ancient orators discovered that by not completing a logical argument, but rather by letting an audience piece it out for themselves, they were better able to convince the audience of the rightness of their conclusions.  Laying things out for people leaves them unconvinced.  Making them work things out for themselves gives them possession of the information, and allows them to make it their own.

4. Talk About What You Learn — Reading a book is useless if you can’t retain what you’ve learned.  The best way to retain the information in a tech book is to use it.  Unfortunately we aren’t always afforded opportunities to use what we know.  We do, however, always have outlets to talk about what we know, and the process of talking not only forms new neural pathways in our brains, thus increasing retention, but allows us to correct our mistakes and misconceptions.  Talking to other developers working on the same technology is optimal.  If that is not possible, however, blogging or writing to newsgroups can serve the same function.  They keep the technology ever in your mind, and you can add on to it or take away from it as you go along.

All of this may be pretty obvious, but then one would think that figuring out how to write better tech books should also be pretty obvious — and it isn’t.  Learning new technologies is generally considered one of the "soft" problems of IT.  By now, however, we have all had enough industry experience with reading tech books that it is clear this is not the case, and it is probably time to throw tech books onto the mound with all of the other "hard" problems of IT, like how to retain good people and how to complete a project on time.

Antivirus Software Blocks Outgoing Mail

general

I use Windows Live Mail to access my Comcast email account.  Whenever I try to send emails, I get this lovely message:

A TCP/IP error occurred while trying to connect to the server.

Subject ‘Re: REQUEST FOR URGENT BUSINESS RELATIONSHIP’
Server: ‘smtp.comcast.net’
Windows Live Mail Error ID: 0x800CCC15
Protocol: SMTP
Port: 25
Secure(SSL): Yes

Normally I wouldn’t care, but in this case there is a former general’s widow in Nigeria who wants to offer me a lucrative business proposal.  I can’t go into details, of course, but it is basically a sure-fire thing, and the only thing now preventing from being a very wealthy man is this problem with sending emails to Comcast’s SMTP server.

The problem turns out not to be on Comcast’s end, however.  My problems with Comcast typically involve billing and service interruption, not basic technology.  Consequently, I began looking elsewhere to track down the issue.

The culprit turns out to be my virus scanning software.  There are lots of posts on the Internet claiming that it is the email scanner which muffs up sending.  This is a red-herring, and turning off virus scanning for your emails is, all things considered, not such a great notion.  It also doesn’t really make much sense — why would scanning incoming emails prevent the sending of emails?

I did a little more investigating and found this McAfee log file, which reveals what is really going on.

4/5/2008    12:04:39 PM    Blocked by port blocking rule     C:\Program Files\Windows Live\Mail\wlmail.exe    Anti-virus Standard Protection:Prevent mass mailing worms from sending mail    76.96.30.117:25
4/5/2008    12:14:01 PM    Blocked by port blocking rule     C:\Program Files\Windows Live\Mail\wlmail.exe    Anti-virus Standard Protection:Prevent mass mailing worms from sending mail    76.96.30.117:25

 

Ho ho.  McAfee is blocking my port 25, purportedly to prevent zombies from taking over my machine and sending out spam messages.  Which makes perfect sense, since if I can’t send out emails, then a zombie impersonating me on my own computer will also not be able to send out emails.  It’s a let’s bomb them all and let God sort out the emails sort of solution — effective, but somewhat heavy handed.

So, with your permission, I’m going to disable my anti-virus software’s port 25 blocking.  I’m not sure of the ultimate impact upon humanity, but it would be rather convenient for me.

Some of my favorite blogs have closed down over the years due to the difficulty of maintaining a high quality blog — Teju Cole, Heaven Tree, Varieties of Unreligious Experience, Giornale Nuovo.  If mine goes down in the near future, however, you will know that it is due not to the high quality of the writing — which happens not to be one of its virtues, I fear — but rather to the incredible wealth that has fallen into the author’s lap.  I’ve read many sad final posts over the past year, but mine shall certainly be a felicitous one: this blog has closed down because the author moved into a higher tax bracket!

Thank you, thank you my anonymous Nigerian general’s widow.  And a pox upon McAfee, whose spam blocker almost prevented me from concluding this fortuitous enterprise.

Install Visual Studio 2008 beta without a DVD Burner

I had a weird problem with my DVD player, such that while I was able to burn the Visual Studio 2008 image successfully, I was not able to use it to install.  Instead, the DVD would just lock up my XP operating system.  So I resorted to my backup plan, which involved simply mounting the image as if it were a media device and running the install from there.

I was able to do this using free software provided by Microsoft called the XP Virtual CD Control Panel.  But first, a public service message: beta software such as Visual Studio 2008 should not be installed on a production machine since it is not supported.  Likewise, the Virtual CD Control Panel is unsupported, by which I mean if you have problems with this you can’t call Microsoft for help, and should be installed at your on risk.

With that out of the way, the Visual Studio 2008 (Orcas) beta image file can be downloaded here, while the Virtual CD software can be gotten here.  The Virtual CD download is a executable zip file, which you should unzip to an easily accessible location on your harddrive.  It includes the VCdControlTool executable, a readme file, and a file called VCdRom.sys.  Copy VCdRom.sys file to your system32\drivers directory.

VCdControlTool

  1. Run VCdControlTool.exe
  2. On the first run, the driver will not have been loaded yet, so click “Driver control”, click “Install Driver”, navigate to the %systemroot%\system32\drivers folder, select VCdRom.sys, and click Open. Click “Start”. Click OK.
  3. Click “Add Drive” to add a drive to the drive list. Ensure that the drive added is not a local drive. If it is, continue to click “Add Drive” until an unused drive letter is available.
  4. Select an unused drive letter from the drive list and click “Mount”.
    Navigate to the directory to which you downloaded the OrcasBeta2VSTSX1394647.img image file.   In your dialog window, change the “files of type” option to All files (“*”). Now you should be able to see the Visual Studio 2008 image file. 
  5. Select the image file and click “OK”.  (You can leave all the option check boxes unselected.)
  6. Return to your windows browser, where you should find the image file under Devices with Removable Storage.  Double click it to begin the install.

orcasinstall

Session Expired Monitor with ASP.NET AJAX

timeout

code download

Sessions are a way of preserving information on a web site between page hits, allowing the programmer to emulate a stateful application when, in fact, web pages are not really stateful.  They are also one of the banes of web development, since sessions eventually timeout when there is no interaction between the user and the web app for a prolonged period of time.  In ASP.NET, this period has a default of 20 minutes, which is really hardly enough time to pick up a donut, refill one’s coffee, and chat with fellow workers before returning to one’s computer.  What this often means is that the user, upon returning to their computer and continuing work after a 20 minute break will find that all of the data entry they have been doing has been lost.  Worse, strange errors will begin to appear in his web browser if the loss of a session is not handled gracefully. 

The most common workaround is to increase the session grace period, called the session timeout.  This is set in your web.config file, and typically looks like this (the timeout period is measured in minutes):

  <system.web>
    <sessionState
      mode="InProc"
      cookieless="false"
      timeout="20"
     />
  </system.web>

A second way of handling this is to add extra code to an app that keeps the session state alive even if the user isn’t doing anything.

A third, and the most common, way is to provide code that redirects a user to a “session expired” page if they try to interact with a web page for which the session has timed-out.  This can be a bit awkward, however, since it is a passive solution that can cause the user some dismay as they hit a submit key only to be taken to a completely unexpected page.

This post deals with an active approach to the same problem.  When the user’s session has expired, it will generate a popup message in the user’s browser window letting him know that he has been inactive for too long.  Additionally it can redirect the browser to a new page with a warning message letting him know what happened.  The user still loses all of his work, of course, but at least this way he knows what happened when he returns to his desk following his coffee break.

This solution uses three tricks.  One is the event model for Master Pages in ASP.NET:  whenever a Content Page is refreshed, its OnLoad event is called,  along with the OnLoad events of the Master Page and any user controls hosted by either the Content Page or the Master Page (the actual order of these events is 1. controls on the Master Page, 2. controls in the Content Page, 3. the Master Page and finally 4. the Content Page).

The second trick is the way ASP.NET Extensions Timer control gets reset.  This is done simply by setting the interval to a new value.  Every time the interval is set to a new value, or even the same value, the countdown on the timer begins again.

The third trick is that the session timeout one sets in the web.config file can be read programmatically simply by querying a property of the Session object.

Putting all of this together, one can build a web user control that simply sits on a Master Page and knows when the user session is ready to expire.  It resets itself to the full timeout period any time a Content Page is refreshed.  when the session expires, the user control can raise an informative message, redirect to another page, or, potentially, simply extend the session timeout (not covered here, but easy to do if you are interested).

A user control to monitor the session timeout is included in the code sample linked at the top of this post.  Here is how you can build your own.

Session Timeout Monitor Recipe:

Ingredients:

  • One Master Page
  • One User Control
  • An Update Panel
  • An ASP.NET Ajax Extensions Timer
  • A Panel control
  • A Button control

1. Create a new User Control in your project. 

2. Drop an Update Panel on the User Control and set its mode property to “Always”.

3. Add an Extensions Timer (not to be confused with the Futures TimerControl) to your project, dropping it in the Update Panel.  Name it TimerTimeout.

Normally, this configuration of the timer control and a conditional update panel is used to refresh a portion of a web page on a regular schedule, for instance in order to create a self-updating clock display.  In this case, however, the timer and update panel are used simply to trigger a notification that the session has expired. 

4. In the User Control’s code behind, add the following lines to the OnLoad event:

        protected void Page_Load(object sender, EventArgs e)
        {
            int milliseconds = 60000;
            TimerTimeout.Interval = Session.Timeout * milliseconds;
        }

This event will be called any time a content page is refreshed.  Whenever this happens, the code inside the event handler resets the AJAX Extensions Timer control to the full session lifespan as set in the web config file, in effect making the timeout for the Timer match the timeout for the session.

Since the Timer control’s Interval property is measured in milliseconds, while the session.Timeout is measured in minutes, a conversion factor of sixty thousand must be used to translate one time period into the other.

To finish this notifier, the Timer’s Tick event needs to be handled.  The Tick event gets called when the Timer’s Interval finally runs out.  In this implementation, the Tick event can either generate a popup message or cause a page redirect.

5. Place a Panel inside the Update Panel.  Set its Visible property to false.

6. Write a simple message inside the Update Panel, such as “Your session has expired.”

7. Drop a Button inside the Panel.  This Button will be used to allow the user to hide the popup message.

8. Add a public property to the User Control called SessionExpiredRedirect:

        private string _sessionExpiredRedirect;

        public string SessionExpiredRedirect
        {
            get { return _sessionExpiredRedirect; }
            set { _sessionExpiredRedirect = value; }
        }

This will be used to set the web page to which the Timer will redirect the user upon session timeout.  If no value is set, a popup message will appear, instead.

9. Handle the Timer’s Tick event:

        protected void TimerTimout_Tick(object sender, EventArgs e)
        {

            if (!string.IsNullOrEmpty(SessionExpiredRedirect))
            {
                if (SessionExpiredRedirect.IndexOf("~")==0)
                    Response.Redirect(
                        VirtualPathUtility.ToAppRelative(
                        SessionExpiredRedirect));
                else
                    Response.Redirect(SessionExpiredRedirect);
            }
            else
                this.PanelTimeout.Visible = true;
        }

This handler checks to see if a value has been set for the SessionExpiredRedirect property.  If not, it makes the Panel control inside the Update Panel visible.

10. To make the Panel control truly popup, set its CssClass property to “timeoutMessage”.  Add the following css style to the page.

<style type="text/css">
.timoutMessage
{
    position:absolute;
    top:100px;
    left:200px;
    background-color:#F5F7F8;
    border-style:groove;
    border-color:Navy;
    padding:15px;
}
</style>

11. Finally, compile this User Control and drag it on to the Master Page.  In design mode, the user control will display a misleading exception message.  Just ignore it.

12. Make sure the Master Page includes an ASP.NET AJAX Script Manager component.

This completes the recipe.  Any Content Page in this project will now automatically include the timeout monitor you have built.  Cookies are optional: this recipe will work with a session managed either with cookies or in cookieless mode.  It will only work if the session mode is InProc.

Garnish with buttered radishes.  Serve at room temperature.

(Code snippets formatted using manoli.net.)

C Sharp’s Double Question Mark Operator Recipe (??)

riddler

At a recent Microsoft conference, the presenter did some quick programming that raised a gasp of excitement from the audience (I kid you not).  He inserted two question marks in a line of code as if they were an operator and Intellisense did not protest.

“Is that a new language feature in .NET 3.5?”, a member of the audience asked.

The presenter looked somewhat puzzled.  “No, it’s in 2.0.” 

At which point half the audience suddenly realized that this was a secret 2.0 feature they could now use to impress friends and colleagues, while the other half smiled knowingly because they had been using it for over a year.  Such is the way programmers distinguish the wheat from the chaff.

So, if you aren’t using the Null Coalesce Operator, yet, you should.  It is basically a syntactic device for setting a default value for nullable types.  The ?? Operator is the equivalent of the ISNULL function in T-SQL, or the NVL function in PL-SQL, and is very handy when you are trying to translate database values into your business classes.

If, for instance, you have a nullable number type in your Oracle database, or a nullable int in your SQL Server database, it is very convenient to map this to a nullable int in your C# business object.

int? myNum = null;

or

Nullable<Int32> myNum = null;

Being now able to represent this database value, you probably also want to be able to test for the null case and return an alternative value if it turns out to be true.  Here are four ways to do the same thing, in increasingly cool ways, because they are increasingly obscure.

With an IF ELSE block:

if (null == myNum)
    return -1;
else
    return myNum.GetValueOrDefault();

With a SWITCH block:

switch (myNum)
{
   case null:
        return -1;
   default:
        return myNum.GetValueOrDefault();
}

With a Ternary Operator:

return myNum == null ? -1 : myNum.GetValueOrDefault();

And with a Null Coalesce Operator:

return myNum ?? -1;

 

For those who think that in coding compactness == elegance, then this is the syntax for you.  For everyone else, it is a nice recipe you can use to impress co-workers at the next code review.  The most likely, and desirable, response will be:

??