Bill Blogs in C#

Bill Wagner discusses C#, LINQ, and other items of interest

October 2005 - Posts

The one where I stop believing Google does no evil

It’s time to start thinking about the actual activities, instead of simply believing that Google does no evil.

Yes, this is my blog entry about Google’s print activity and the lawsuits filed by several publishers and the author’s guild.

First, let me say that I’m all in favor of preserving information, and making it easier to find information. Let’s start with some examples. Anyone that has visited my house has commented on the large number of Grateful Dead tapes I’ve got. All are copies of concerts, made by friends and acquaintances, and traded with other folks. All were free. Ask any deadhead, and you can start your own collection. For you young folks that don’t remember tapes, you can now do the same with digital audio files: http://www.archive.org/audio/etreelisting-browse.php?cat=Grateful%20Dead

But, there are important points: The Grateful Dead had always allowed, and even encouraged this activity. If you bought tickets in the ‘tapers section’, that entitled you to bring taping equipment and create a copy of the show. The only restriction: you could not profit from the tapes you made. You could listen to them, you could trade them, you could distribute them any way you wanted, but you could not profit from them.

Next, let’s consider digitizing and preserving rare and at risk content. We developed and maintained an application for the University of Michigan graduate library (http://www.srtsolutions.com/PageTag/index.htm) that has been used to scan and store the rare books in the U of M Graduate library. This project enabled more people at U of M to work with these volumes. They are rare, old, and can be damaged by normal environmental conditions. Once again, the project was not for profit, and enabled researchers to access these rare volumes. Mickey Hart (yes, that’s another Grateful Dead reference) donated time, money, and expertise to work with the Smithsonian Institute to catalog and preserve early 20th century music. You can read a summary here: http://www.cnn.com/SHOWBIZ/Music/9812/02/mickey.hart.wb

Finally, before I get to Google print, let’s discuss excerpts. Yes, this is the part where I respond to the obvious question about authors and publishers promoting their books. If you go to my Effective C# page you’ll see links to some selected pages that have been excerpted on the web. Key point: Exceprts. Not the entire book. None of the owners of these website (except Addison-Wesley) have the entire book content. They could not possibly re-publish the entire book.

Now let’s move on to the Google Print initiative. The first big difference: Google is a for-profit enterprise. No matter how you slice it, Google exists to make money. My first examples were non-profit activities: The Grateful Dead mandated that you could not profit from the tapes you made, or copied. The U of M Graduate library could give more students access to rare books by allowing people to view the images, rather than working in the environmental controlled stacks. The Smithsonian project preserved some early American music that otherwise would have been lost forever. Google will make money from Google print, and the only way I see that being possible is at the expense of publishers and authors.

Now, let’s look at my specific technical concerns. Google is currently saying that they will only provide small excerpts based on search terms. Ok script kiddies, here’s your challenge: Develop the set of queries that will return the entire 5 Harry Potter books, one page at a time. While I have better things to do with my time, I don’t doubt that it’s possible. If Google has the entire content, I’m sure the young hungry developer is out that that can create those scripts.

To finish this mild rant, let’s look at it from the other direction: I’d like the source code to everything Google develops. I promise that I will only excerpt a few functions as examples of ways to solve a given technical problem when a reader asks. I’m betting that Google won’t take me up on it.

So, I’m against it. Period. Google can scan excerpts of published works, but should not be allowed access to the full content.



David Yack's post
Another author's opinion
Bill Evjen's thoughts
Another author (and fellow MS Regional Director
David Winer's opinion
The one where Google goes too far
Dara Obasanjo's post
Dare on Google Print and Marketing blogs
Posted by wwagner | with no comments
Filed under:
Eric Maino returns to Michigan

I just heard today that Eric Maino, a former student ambassador, and now a member of the C# team at Microsoft, is returning to Michigan for the Nov 8th VS 2005 Launch event.

For those of you that don't know, Eric was the student ambassador at Grand Valley State until he graduated last year, and was immediately snatched up by Microsoft.  Now, he's a member of the C# team.

Eric will be joining Josh Holmes, me, and other regional .NET experts at the "Ask the Experts" booth.  Stop by and say hello.

Rumor has it that Drew Robbins, the Dancing DE, is super excited about this.



Eric's weblog
Just another C# team Member
The original Dancing DE
Drew's original video performanc
Drew super excited
His encore performance
Posted by wwagner | with no comments
Here's one of his newest essays

Charles Petzold wrote an essay that was related to his talk at the NYC User's Group, "Does Visual Studio Rot the Mind?"

One the one hand, I think the tools have grown as the complexity of the software we build has grown.  I believe that means VisualStudio should be doing more for us than earlier generations of tools had.

On the other hand, Charles is correct in saying that the code generated by Visual Studio is often of dubious quality:  It works, but it's often an example of poor practices, not best practices.

He's also spot in in saying "And yet, IntelliSense is also dictating the way we program."  It's worth a read. 

Later he says "I also discovered that some problems do require some thought before you code them."  If nothing else, I can only hope that one day, thinking before coding becomes as popular as agile programming.  Thank you Charles.



Charles' Paper
Does Visual Studio Rot the Mind?
Posted by wwagner | with no comments
Filed under:
Or is that just for the testers?

I read this interesting analysis of getting beta testers for an Open source project today. Apparently BitDefender is paying beta testers in beer.

My favorite quote:

"Beta testers are vital for any new software product, but they're absolutely essential for open-source projects, since companies that sell such software often don't have big quality-assurance departments"

So, does that mean that in the Open Source Community, the "volunteer army of developers" views "customers" as "a volunteer army of testers"?

 



The Business week article
Beta Testing for Beer
The application
Do you want to test for free beer?
Posted by wwagner | with no comments
But I think I'm still taller than he is

I've been following the progress of the Fat Cyclist for a while now.  (In part, it's because I know his alter-ego mild-mannered editor guy ... Well, never mind.  I can't reveal his alter ego).

Anyway, it's finally happened:  I weigh more than the fat cyclist.  He broke through the 160 lb barrier (my normal weight) today.



Oreos and a smaller fat cyclist
Today's entry
The Fat Cyclist home
One man's journey to a thinner middle-aged biker guy

Posted by wwagner | with no comments
Filed under:
OK, so this is stale, but it's still useful

I had meant to blog about this earlier, but something else always came up.

Neil Cowburn created a great little addition to add annotations (following the format in the SLAR and .NET Framework Design Guidelines) to your source documentation. 

It's amazing useful when you're adding comments from code reviews, or other post-coding reviews.



Neil's article
Grab the extensions here
What I wrote about the SLAR
That's Standard Library Annotated Reference for the rest of you
What I said about the .NET Framework guidelines
This is a great look inside the .NET Framework
Posted by wwagner | with no comments
Filed under:
Just one of those things I won't remember unless it's written down

I spent too much time debugging this, because there is precious little diagnostic info.

I was working on a .NET application that needed to launch a console application to perform some processing.  The application followed the old style unix standard of using exec() to launch other applications that it used to complete processing. So far so good. The System.Diagnostics.Process class did just about everything I needed. Well, I wanted to run the exe without any window, and capture standard out so I could tell the user what happened.  My code looked like this:

string exePath = string.Format("{0}\\{1}", dir, "theUtility.exe");
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo( exePath );
startInfo.CreateNoWindow = true;
startInfo.RedirectStandardOutput = true;

startInfo.UseShellExecute = false;
startInfo.WorkingDirectory = dir;
System.Diagnostics.Process process = System.Diagnostics.Process.Start( startInfo );
// Wait for it to die...
process.WaitForExit();

Well, that RedirectStandardOutput flag was a problem. If the utilty ran to completion by itself, all was good. However, it the utility launched another app, the redirect caused the subordinate executable to hang.

The end final rule: You can't redirect standard output using ProcessStartInfo if the executable you're launching may launch another exe.The launched exe will hang.



Posted by wwagner | with no comments
Filed under:
Register for the VS 2005 Launch event in Detroit

Hey local .NET folk:

The VS 2005 Launch tour is coming to Detroit on Nov 8th.  You can register here:

Click here to register

I'll be at the User Group table, and the Ask the Experts booth, so stop by and ask questions.



Posted by wwagner | with no comments
Peter is always thorough.

Peter N. Roth reviewed "C# Precisely", and "Effective C#" in the latest issue of C++ Users Journal.

You can read the full review here: http://www.cuj.com/documents/s=9897/cuj0510book/

I'll only add one point:  Peter rightly complains about numerous combined word errors that were introduced in the typesetting process. Those have largely been fixed in the second and subsequent printings. 



Posted by wwagner | with no comments
Filed under:
A question with two answers: No, and Occasionally.

I received this question last week:

I'm still working through and enjoying "Effective C#", unfortunately  my job has really intruded for the past 2 months. I'm at Item 18: "Implement the standard Dispose pattern". It says that you should  implement this pattern if your class uses non-memory resources, so I went back to some programs I had written using the Windows Forms lib that use Pens, Fonts, etc.

My First Answer:

Regarding (1): You should never hold unmanaged resources in static variables. It makes the lifetime management more or less impossible to get right.

Regarding (2): This is why I said what I said for (1). There is no reliable way to make this work. If you release the resources in an instance's Dispose() method, any other instance is broken: the resource is gone, but the static member variables are still in scope. If you don't release the resources in some instance method, it's broken because you never release the resources.

If you really want one copy of the unmanaged resources, wrap them in a type that implements the Singleton Pattern.

So, don't store unmanaged resources in static variables. Ever. It won't work.

Upon Further Reflection:

I'm still not sure it's a common pattern, but there might be some instances where this might work.  It's a small resource leak, but there are instances where you don't really care.

Suppose you create some type that needs to hold a resource that implements IDisposable, and that type will have a lifetime that mirrors your application's lifetime. Well, then a static member variable means that you only create one copy of that resource in your application. However, you'll never release that resource. However, it will get cleaned up when your app exits. So, no real problem. It's a little fragile, because you will have quite a bit of work to do if your application changes later and your resource's lifetime no longer matches the application's lifetime.

When I went to implement the pattern I got confused. My questions are
1) In my classes my unmanaged resources are held in static vars. What should I do?
2) Assuming that after understanding #1, I still want to write virtual void Dispose(bool isDisposing): Do I need to free all the references I've new'd to objects when "freeing managed resources"? If yes, how?



Posted by wwagner | with no comments
Filed under: ,
Breaking 80 at a really tough course (just skip it if you're not a golfer)

Let me start with this: If you’re not at all interested in golf, just skip this one.

I played our club course with my son this afternoon (The U of M, MSU game was on, so it was almost empty). I was playing the blue tees, which measure 6888. I’ve had a couple even 80 scores back there, but I’ve never broken 80. That changed today.

By the ay, my son Scott plays pretty well for his age: He hovers around 100 at the silver tees (5767 yards).

I had to finish strong for my 79, but here’s the entire shot-by shot description: (Like I said, if you’re not a golfer, just skip this entire entry. I’ll return to C# topics come Monday.)

Hole 1: 415 yard par 4, with 5 sandtraps in the middle of the fairway at the landing area. You have to drive toward the left or right side of the fairway. I didn’t. I hooked my drive into the bunker in the middle of the fairway. I hit a good bunker shot with my 22 degree hybrid, missing the green to the right. Chipped on and missed the putt for an opening bogey: +1

Hole 2: 410 yard par 4, water on the left. My drive just missed the fairway to the right. I put a 6 iron to the back the green, and 2 putted for par: still +1.

Hole 3: 164 yard par 3. I hit my 6 iron a bit thin and put it in the front left trap. Hit a good sandshot, and my par put lipped out: +2

And then came 4. It’s a 557 yard par 5, with trees and OB both left and right, and water in front of the green. I’ve had more big numbers on this hole than I care to remember. Today started no different. I pushed my drive into the trees in the right rough. I had a good opening, so I hit the 3 wood, but it got a little high and clipped some branches. I ended up with about 165 from the green. I pured a 6 iron over the green, to a tricky downhill lie. Hit a great flop shot 8 feet from the hole and saved par: +2.

Hole 5 (403 yard par 4): Hooked by drive into the left fairway trap. Hit an ok hybrid short of the green, tried that flop shot again (20 feet away this time), and two putted for bogey: +3.

Hole 6 (539 yard par 5): I split the fairway with my drive, hit a low 3 wood to about 75 yards, 3/4 lob wedge to 4 feet and drained the putt for birdie +2.

Hole 7 (200 yards, par 3). Followed that birdie with a heel-honker that went 110 yards. Hit a sand wedge to the front of the green, and two putted for bogey: +3.

Hole 8 (394 yards, par 4): Hit the middle of the fairway, pushed a 7 iron into the short right bunker. Took too much sand and barely got out. 3 putts later, finish with a double bogey: +5.

Hole 9 (409 yard par 4): Simply put, I’ve got way too many pellets in the large pond on the right of this hole. So, today, I hit a pull-hook into the left rough, with a buried lie. Hack it out with a 7 iron, and hit a log wedge to 10 feet. Two putts leaves me with a bogey and a 42 (+6) for the front nine.

I figured there was almost no change to break 80 this time, but we played on, and I do seem to often do well on the opening holes on the back nine.

Hole 10 (394 yard par 4): Drove it into the right rough, put a 6 iron just off the green, two putts for par: +6.

Hole 11 (379 yard par 4): Split the fairway off the tee, put a nine iron to the front fringe, which was planned because the hole location was way up today. Two putts, and another par: +6.

Hole 12 (184 yard par 3): The pin was back, and a breeze was straight into me, so I hit the 22 degree hybrid. I pured it and airmailed the green, short-siding myself again. I hit a pretty good lob wedge, and my 10 ft par putt just missed: +7.

Mindset interlude: I have to play the last 6 holes in even par to break 80. I figure I don’t have a chance. Especially since I really dislike the way the 13th hole sets up from the blue tees. The tee is off to the right of the fairway, and I feel like I need to aim right at the pond on the left of the fairway to hit it. It never fails that I’m in the right rough.

Hole 13: (par 4, 387 yards): Once again, I’m in the right rough amongst the trees, and I have to punch out. A wedge puts me on the green in three, and two putts give me another bogey: +8.

Hole 14 (475 yard par 5): This hole can play shorter. Your second shot can either go over a large pond to try and hit the green in two, or play to the right of the pond in the fairway and make it a true 3 – shot hole. I split the fairway again, but didn’t hit it far enough to go for it in two. I hit the three wood to the right and left a 60 yard lob wedge to the pin. I hit the lob wedge to 5 feet and made birdie: +7

Hole 15 (404 yard par 4): I split the fairway, and put a 9 iron to 3 feet, made the putt. There’s more to the story though. The wind was behind me and left to right. So, I aimed a bit left of the pin. The wind did not move the ball at all, so it landed left of the green on a slope and bounced straight right. Still, the birdie counted: +6

Hole 16 (205 yard par 3): Pulled my 19 degree hybrid into the front left trap, hit a mediocre sand shot that caught the swale between the first and second tiers, rolling back to the front of the green. Unfortunately, the pin was in the back. Two putts later, I’m +7 again.

Mindset interlude: I hate 17. It’s a long par four, with OB left and water right. To make matters worse, the tee aims you well right of the fairway.

Hole 17 (425 yard par 4): I hit my usual big block into the trees by the creek. But, luck was on my side: it hit a tree solid and came right back at me. I was still 240 yards from the green, but I found it. I hit a 5 iron up the fairway, put a lob wedge on the green and made a 20 footer to save par: Still +7.

Hole 18 (544 yard par 5): This is a great finishing hole. It finishes with a gentle curve to the right, hugging a creek that runs into a pond. I hit an OK drive, but was in the left rough. I followed that with a very nice (but not really long) 3 wood cut shot that put me back in the fairway about 160 yards from the green. I put a 6 iron to the back of the green right at the swale that separates the left and right tiers. I hit my first putt into the swale (I played about 15 feet of break) and it finished 3 inches short of the hole. I tapped in the par putt with my 10 year old son yelling “Noonan!” in my ears.

All in all, a fun round.

And, I promise to return to real tech tomorrow.



Posted by wwagner | with no comments
Filed under: