Archive for July, 2005

Does ANYONE Comprehend ASP.NET Web Projects?

Once every few weeks I find myself wrestling with these foul beasts. And each time, I find the following phrase echoing in the empty space between my ears.

Mit der Dummheit kämpfen Götter selbst vergebens.

I have been making every attempt to avoid dealing with them. For the most part, a series of NAnt scripts have insulated me. But now and then I need to get one working for the sake of helping one of the many lost souls who depend on them.

Last time, I took screenshots.

The first step was to try to add the project to a solution.

Creating an ASP.NET web project - Step 1

It wants me to enter the URL of the project, so far so good…

Creating an ASP.NET web project - Step 2

Now we have the first sign of trouble. The URL bit appears to have punted to a standard file open dialog.

Creating an ASP.NET web project - Step 3

I faithfully yet skeptically select the file, but I have the sinking feeling of having been here before.

Creating an ASP.NET web project - Step 4

Ah yes, I remember now.

Creating an ASP.NET web project - Step 5

So there you have it: web projects are an ouroboros; they are a maddening riddle, answered only by another question.

A Macroeconomic Theory of Texas Holdem

I am having a banner day as an intellectual, it being no coincidence that my television is currently broken. I could take this excellent opportunity for creative output to bemoan yet another unfathomably stupid government-funded “power of prayer” study, but I opted for a more lighthearted subject.

To be completely candid, I started doing just that, but I depressed myself too much to finish it.

Therefore, I will regale you, the reader, with a dissertation on another utterly important subject. Namely, gambling.

Trading emails with a friend the other day, I described the poker craze that is gripping the nation as “the pet rock of this era.” I was immediately taken to task and told to defend this statement.

The argument I was given went about like this.

If one is an expert at poker, one can expect to win consistently. That’s much more than you can hope to get from other games of chance like blackjack or craps, so why would anyone lose interest in poker, given the unwavering popularity of those games?

Forget that it’s on television; once you’re into poker, I think you are hooked for life.

First let me say that I am not backing my response with any hard data. This is purely an academic exercise.

Poker suffers from an important handicap: it is necessarily worse than a zero-sum game. The winners are few, and in large tournaments or online walk away with somewhat less than what the losers have given up.

The idea that an adroit player can consistently come out the better appears to be all-too-true. But rather than being an asset, this is the very reason why poker will not continue in popularity. For every player that wins consistently, there are players who lose just as consistently.

These players plainly will not be interested indefinitely. They have sprouted like reeds from the Nile-esque deluge of ESPN coverage for the time being; in fact, this is making it significantly easier to be one of the lucky few who leave with chips.

When the plebeian interest wanes, the game’s talent bar will steadily rise. Ultimately, nearly all of those who currently style themselves as among the upper echelons will look around only to see that they are in free fall.

This kind of analysis is not difficult to derive; why is it that so few take the trouble to do it?

NAnt Task to Enforce VB.NET Project Settings

Here is a NAnt task I am using to enforce VB.NET project settings during a build. This is useful if you can’t use <vbc> to compile your projects.

Usage example:

  <vboptions compare="Binary" strict="true" explicit="true"
      path="${projectfile}"
      if="${path::get-extension(projectfile) == '.vbproj'}" />

The code:

/// <summary>
/// Enforces specific VB settings on a particular project.
/// </summary>
[TaskName("vboptions")]
public class VbOptionsTask : Task
{
    private string _path;
    private bool _strict;
    private bool _explicit;
    private string _compare;

    [TaskAttribute("path", Required=true)]
    public string Path
    {
        get { return _path; }
        set { _path = value; }
    }

    [TaskAttribute("explicit", Required=false)]
    public bool Explicit
    {
        get { return _explicit; }
        set { _explicit = value; }
    }

    [TaskAttribute("compare", Required=false)]
    public string Compare
    {
        get { return _compare; }
        set { _compare = value; }
    }

    [TaskAttribute("strict", Required=false)]
    public bool Strict
    {
        get { return _strict; }
        set { _strict = value; }
    }

    private bool CheckOption(string opt, bool val)
    {
        bool on = (string.Compare(opt, "On", true) == 0);
        return (on == val);
    }

    private void ValidateOption(XmlNode node, string attr, bool val)
    {
        XmlAttribute a = node.Attributes[attr];
        if(a == null || !CheckOption(a.Value, val))
        {
            throw new BuildException(
                 string.Format("The build option '{0}' in project {1} is not set to '{2}.'",
                     attr, this.Path, (val ? "On" : "Off")
                     )
                 );
        }
    }

    protected override void ExecuteTask()
    {
        XmlDocument proj = ProjectFactory.LoadProjectXml(this.Path);
        if(proj == null)
        {
            throw new BuildException("Could not load project xml for: " + this.Path + ".");
        }
        XmlNode settings = proj.SelectSingleNode("//VisualBasic/Build/Settings");
        if(proj == null)
        {
            throw new BuildException(this.Path + " is not an Everett .vbproj file.");
        }
        XmlAttribute c = settings.Attributes["OptionCompare"];
        if(c == null || string.Compare(c.Value, this.Compare, true) != 0)
        {
            throw new BuildException(string.Format("The project {0} does not have Option Compare set to {1}.", this.Path, this.Compare));
        }
        ValidateOption(settings, "OptionStrict", this.Strict);
        ValidateOption(settings, "OptionExplicit", this.Explicit);
    }

    public VbOptionsTask()
    {
        _compare = "Binary";
        _explicit = true;
        _strict = true;
    }
}

DataSetSurrogate Remoting Sink

I have received a trickle of requests for some code that I have written and alluded to here and here: namely, a custom Remoting sink that swaps DataSets for DataSetSurrogates as they pass by.

Unfortunately, it would not be legal for me to release this code. Sorry. However, I think I can give a general outline of it without giving away the farm.

The first thing I should say is that the cure for your remoting performance woes is probably not the DataSetSurrogate in every case. (Review what I have said here and here for more information).

If it’s at all practical, my recommendation to you is to simply avoid using DataSets in n-tier situations.

Still here? Great.

Ok, with the disclaimers out of the way, the code works in two pieces: the remoting sinks and the ISerializationSurrogate. The serialization surrogate is relatively easy to implement, if you’ve gotten this far.

The sinks are a little more clever. I wanted to continue using the framework BinaryFormatter sinks, since they added a lot of things to the mix that I didn’t feel like re-implementing.

However, there’s no way for you to modify how the BinaryFormatterClient/Server sinks do their serialization. More explicitly, there’s nowhere to plug in the ISerializationSurrogate object that you’ve written.

The client and server sinks actually pull-the-old-switcheroo on the messages coming through the pipe. That’s the clever bit.

So I am leaving the framework sinks there, but altering the messages that go through them. The messages they see have a binary representation of the “real” messages appended as a parameter.

That’s the fastest way to write the sinks. If you implement complete formatter sinks, you can accomplish it a little more efficiently.

Hope this helps. Sorry that I can’t be more specific. If you’ve gotten this far without your head exploding, trust me, you’re smart enough to write these classes.

Anyway, the result is significantly faster for many kinds of data. Not for all kinds of data.

The Mandelbrot Set meets Rapid Development Tools

The first time I wrote this program, it was a DOS-based program. I wrote my own putpixel routine in x86 assembly for it (among other things). It took me a few sleepless nights to finish writing it.

Today I got bored and wrote it again. It took less than a half hour this time.

The Mandelbrot Set in C#

Somehow, it was more satisfying the first time.

John Dvorak Benefits from the Public Stupidity he Decries

Something has been bothering me about John C. Dvorak’s site for the last few days. This post in particular drove me to write about it. Here is a screenshot of the post. I would like to point out two things.

John Dvorak promotes pseudoscience

Figure (1) is John Dvorak complaining about public ignorance and stupidity. For this, I would normally applaud him. Figure (2) is John Dvorak profiting from public ignorance and stupidity.

Perhaps Dvorak isn’t in control of the content of that ad. If that’s the case, hopefully he’ll stop using that particular vendor. If he doesn’t, I don’t think there’s anything you can call this behavior other than every gadfly’s favorite insult, hypocrisy.

Some of the comments to his post are seriously pretty scary. Somehow, these people are allowed to procreate.

There is a slight parallel here to My God Problem, which is a thought-provoking article by Natalie Angier that appeared in Free Inquiry magazine. Simply put, the point is this: you cannot turn a blind eye to certain (popular) superstitions and still bemoan the public’s inexplicable distaste for evolution.