Archive for the ‘.NET’ Category

Faking Multiple Inheritance with Event Handlers

I'm going to take a page from the Book of Darrel and post some design patterns whenever I realize that I'm using them. I'd like to be careful because I think that there are a few camps when it comes to design patterns:

  1. Design patterns are very important, very specific, and are a great thing to quiz people about in an interview.
  2. Design patterns are more of a feel thing, something that is figured out when you're factoring code. There is no way you will not discover these on your own, if you are experienced and smart.

I lean to the second category. The quizzers tend to be solipsists and may know little else (you'll see the same attitude with plenty of other development topics).

Now that you know how to take my writing about design patterns, let's suppose that you want to make a Windows form that becomes a little translucent when it is inactive. That may or may not be annoying, but there is a very straightforward way to make it happen:

// Form that becomes transparent when it is inactive
public class Foo : Form
{
    private const double c_InactiveOpacity = 0.25d;
    private double _prevOpacity;

    protected override void OnDeactivate(EventArgs e)
    {
        _prevOpacity = this.Opacity;
        this.Opacity = c_InactiveOpacity;
        base.OnDeactivate(e);
    }

    protected override void OnActivated(EventArgs e)
    {
        this.Opacity = _prevOpacity;
        base.OnActivated(e);
    }

    public Foo()
    {
        _prevOpacity = 1.0d;
    }
}

Which works fine, unless you want TWO forms that do that, the second with a special base class not related to the heirarchy of the first.

public class Foo2 : SpecialForm
{
    // criminy
}

This conundrum could be resolved in a few ways:

  1. Ctrl+C, Ctrl+V.
  2. Multiple base classes.
  3. What I am going to call the "Extender Pattern."

If you picked the first option, I think it'd be better for both of us if you unsubscribed from my feed. The second option would work fine, but CLR languages don't support it. Some days this bothers me, but most days I think it's a good thing. Especially when I factor a solution that is just as elegant.

I'm calling that solution the "Extender Pattern" without bothering to find out if anyone has used this term to describe anything else. As I explained above, this is more about artistic sensibility than it is about hard rules and book learning. Not that I'm anti-book learning.

The basic idea is this: you have a set of components that support certain properties, methods, and events. The forms, in this case. You add in to the mix a set of small objects whose only responsibility is to wait for events from the components and make very directed changes to them.

So here is such a class for the problem stated above:

// Alters the target form's transparency level
// when it is activated/deactivated.
public class TransparencyExtender
{
    private Form _target;
    private double _prevOpacity;
    private const double c_opacity = 0.25d;

    public TransparencyExtender(Form target)
    {
        _target = target;
        _prevOpacity = target.Opacity;
        target.Activated +=
             new EventHandler(Activated);
        target.Deactivate +=
             new EventHandler(Deactivate);
    }

    void Deactivate(object sender, EventArgs e)
    {
        _prevOpacity = _target.Opacity;
        if (_prevOpacity >= c_opacity)
        {
            _target.Opacity = c_opacity;
        }
    }

    void Activated(object sender, EventArgs e)
    {
        _target.Opacity = _prevOpacity;
    }
}

Given this, we can write our forms very easily:

public class Foo : Form
{
    private TransparencyExtender _tExt =
        new TransparencyExtender(this);
}

public class Foo2 : SpecialForm
{
    private TransparencyExtender _tExt =
        new TransparencyExtender(this);
}

Keep in mind that I am not claiming that this is original. It's really the same as a small secondary base class in C++. However, I think there's value in looking at the same problem in different ways.

In a real application I'm working on, I've written a handful of other window/control styles that can be applied and removed on the fly or from the designer. Again, not original, but I like my little framework. Perhaps I'll post this someday, or turn it into a product.

I like event/message-driven programming the more I try to use it. I'm using Windows Forms as an example here, but it would be wrong to assume that's the only place this could be applied. I've done the same kinds of things in ASP.NET.

Concurrency Approaches Contrasted

Here are a few roughly-equivalent class declarations using different languages and libraries. I say "roughly equivalent" because the implementation details and performance characteristics may actually be quite different in each case. However, the end result of each is that a function on a member variable is called in a non-blocking fashion, synchronized (presumably against other operations on the same class) with the use of some resource A.


// Vanilla C# with locks
public class FooBar
{
    private object A = new object();
    private T _member = new T();
    private delegate void FooBarDel();

    public void Foo()
    {
        FooBarDel del = new FooBarDel(FooBar);
        del.BeginInvoke(
          new AsyncCallback(FooBarDone), del);
    }

    private void FooBar()
    {
        lock(A)
        {
            _member.DoSomething();
        }
    }

    // You can typically get away without this, but
    // the documentation recommends otherwise.
    private void FooBarDone(IAsyncResult r)
    {
        FooBarDel d = r.AsyncState;
        d.EndInvoke(r);
    }
}

// Comega using a chord join pattern
public class FooBar
{
    private T _member = new T();
    private async A();
    public async Foo() & A()
    {
        _member.DoSomething();
        A();
    }

    public FooBar()
    {
        A();
    }
}

// C# 2.0+ using CCR
public class FooBar
{
    private T _member = new T();
    private Port<int> _p = new Port<int>();

    public void Foo()
    {
        _p.Post(1);
    }

    public FooBar()
    {
        activate(!_p.with(delegate(int i)
        {
            _member.DoSomething();
        }));
    }
}

Looking at the other two examples I think it's clear that C# as it stands today is lacking. That's not exactly a groundbreaking statement, I realize, but I haven't seen many examples putting all of these together in one spot.

Comega is very elegant in a situation as simple as this. CCR also seems less mistake-prone than the plain C# version, but the example I picked isn't where CCR really shines.

(One thing I should say is that I'm not sure that the CCR example is correct or even compiles, since the library isn't public yet. I worked this out from reading the whitepaper [pdf]. It's only a few pages, so I recommend giving it a read.)

The goal of CCR has been to allow complex constructs such as this (also from the whitepaper) to be made easily, and dynamically if necessary:


    // The finish operation or the update operation
    // execute with exclusive control, whereas the
    // GetState and QueryState operations execute
    // concurrently. Operations of either type are
    // interleaved safely (using the '^' operator).
    activate(exclusive(p.with(DoneHandler),
        !p.with(UpdateState))
        ^
        concurrent(!p.with(GetState),
        !p.with(QueryState))
    );

Comega, on the other hand, provides static language features. The good news is that since CCR is just a library, it would be usable from a future C# (4.0, one would hope) that incorporated some of the ideas in Comega at the language level for the easier cases.

I had thought it was a shame that none of the Comega concurrency constructs had made it into the 3.0 C# specification. However, with CCR I think I can see why this is the case. CCR, or something like it, should offer a lot of power and flexibility well within the 3.0 timeframe without taking the risk of baking the 'wrong' keywords into C# itself.

Wrote a Concurrency Library for Everyone

Herb Sutter says the concurrency revolution is coming. This guy says, “*** you!! the concurrency revolution is coming!”

That is the kind of attitude we need in the industry. We need more in-your-face greeks and fewer genial mustachioed C++ architects. Call me crazy.

I know this is the type of enthusiasm that is typically found in insane people building anti-gravity machines in their backyards, but I think these guys might be on to something with their Concurrency and Coordination Runtime (CCR).

I highly recommend watching the video–even if you have no idea what these people are talking about. Seriously mind-blowing stuff.

Making a DataSet Read-Only

Let's say you're writing a component that makes a DataSet available to a number of clients. The DataSet is expected to persist in your application for a while, and be used in code written by many different developers.

You could carefully craft an email explaining that,

Hey everybody, this DataSet is shared. Please don't change the data in it for the purposes of your own piece of the application. That could create some odd bugs that would be really hard to track down. If you need to do something like that, please make a copy of the DataSet first.

I suppose you could do that, if you wanted to waste your time. You could always create a copy of the DataSet before handing it over to anybody, but that may introduce some unnecessary performance issues if the DataSet is large. It feels a little like punishing everyone for the bad behavior of a few. If you wanted to actually prevent such problems, you could write a clever class like this that acts like a "lock" on the DataSet.

/// <summary>
/// Class that ensures that clients keep their pesky hands
/// off of a particular dataset.
/// </summary>
internal class DataSetLock
{
    [Conditional("DEBUG")]
    public static void Install(DataSet ds)
    {
        if (ds == null)
        {
            throw new ArgumentNullException("ds");
        }
        EventHandler thrower = delegate(object sender, EventArgs e)
        {
            string msg = string.Format(
                "You can't change: {0}.", ds.DataSetName);
            throw new InvalidOperationException(msg);
        };

        foreach (DataTable t in ds.Tables)
        {
            t.RowChanging += new DataRowChangeEventHandler(thrower);
            t.RowDeleted += new DataRowChangeEventHandler(thrower);
            t.ColumnChanging += new DataColumnChangeEventHandler(thrower);
            t.TableClearing += new DataTableClearEventHandler(thrower);
            t.TableNewRow += new DataTableNewRowEventHandler(thrower);
        }
    }
    private DataSetLock() { }
}

The "lock" is really an anonymous method that we attach, willy nilly, to all of the change events in the DataSet. We use lexical closure to add the DataSet name passed in to the exception message dozens of caffeine-addled developer brains will be processing shortly. [Note: if you don't think it's lexical closure, go talk to this guy. He's really into the topic.]

I put the ConditionalAttribute on the Install method as well, so as long as you have reasonably good testing coverage this check will just be compiled away in retail code.

Here's a quick usage example:


static void Main(string[] args)
{
    DataSet ds = new DataSet();
    ds.DataSetName = "My Data Set";
    DataTable t = ds.Tables.Add();
    t.Columns.Add("foo", typeof(string));

    DataSetLock.Install(ds);

    // Pow!
    t.LoadDataRow(new object[] { "asdf" }, true);
}

This prints:

System.InvalidOperationException: You can't change: My Data Set.

Enjoy.

Monad Script to Scrub Perfmon Output

Here's the scenario: I had about eight hours of perfmon output, for several hundred counters sampled once per second. I wanted to put this into a database already containing the parsed IIS logs from the same machine, to try to correlate some of the resource utilization peaks with URL's.

The only snag was that Microsoft's LogParser couldn't handle the CSV files that perfmon generated. The input lines were far too long for it.

The call is from heroism. Will you accept the charges?

The solution I came up with was to hack together an MSH script that processed the files. It's not pretty (because it didn't have to be), but here it is.


#
# trim-perflog.msh
#   This pares down a set of enormous perfmon logs to a
#   size that can be managed by the Microsoft LogParser.
#
#   This finds the column indices that we're interested in,
#   then runs through each line in the input CSV file(s)
#   and pulls them out.
#

# The counters in the perfmon trace that we're interested in.
#
$counters =
"(PDH-CSV 4.0) (Eastern Standard Time)(300)",
"\\machine\.NET CLR Exceptions(w3wp)\# of Exceps Thrown / sec",
"\\machine\.NET CLR LocksAndThreads(w3wp)\Contention Rate / sec",
"\\machine\.NET CLR Memory(w3wp)\% Time in GC",
"\\machine\.NET CLR Remoting(w3wp)\Remote Calls/sec",
"\\machine\Process(w3wp)\Page Faults/sec",
"\\machine\Process(w3wp)\% Processor Time",
"\\machine\Process(w3wp)\% User Time",
"\\machine\Process(w3wp)\% Privileged Time",
"\\machine\Process(w3wp)\Private Bytes";

# Prettier names for the counters.
#
$columnAlias = "time", "exceptionsPerSecond",
"contentionPerSecond", "pctTimeInGC",
"remoteCallsPerSecond", "pageFaultsPerSecond",
"pctProcessorTime", "pctUserTime",
"pctPrivelegedTime", "privateBytes";

# Returns an array that contains the index of each of the
# $counters in the csv.
#
function getPerflogIndices
{
    param([System.String]$columns)

    $tokens = $columns.Split(',');
    for($i = 0; $i -lt $tokens.Length; $i++)
    {
        $t = $tokens[$i];
        $t = $t.Substring(1, $t.Length-2);
        $index = -1 ;
        for($j = 0; $j -lt $counters.Length; $j++)
        {
            if($t -eq $counters[$j])
            {
                $index = $j;
            }
        }
        if($index -ge 0)
        {
            write-object $i;
        }
    }
}

# writes a CSV line using the values in $array.
#
function write-array
{
    param([System.IO.StreamWriter]$writer, $array)
    $j = 0;
    $last = $array.Length;
    foreach($a in $array)
    {
        $writer.Write($a);
        if($j -ne $last)
        {
            $writer.Write(",");
        }
        $j++;
    }
    $writer.WriteLine();
}

# Writes a single line to the result CSV file.
# This requires:
#    $writer  - The output stream.
#    $ln      - A single line read from
#                the input stream.
#    $indices - The column indices of the
#                  subject perfmon counters.
#
function write-csv-line
{
    param([System.IO.StreamWriter]$writer,
       [System.String]$ln, [System.Object[]]$indices)

    $vals = $ln.Split(',');
    $j = 0;
    $last = $indices.Length - 1;
    foreach($i in $indices)
    {
        $writer.Write($vals[$i]);
        if($j -ne $last)
        {
            $writer.Write(",");
        }
        $j++;
    }
    $writer.WriteLine();
}

# Trims down the input CSV file. If $names is True,
# writes the names of the columns as the first line
# in the output.
function trim-perflog
{
    param([System.IO.FileInfo]$in, [System.Boolean]$names)

    $r = $in.OpenText();
    $ln = $r.ReadLine();
    $indices = getPerfLogIndices $ln;

    $wr = [System.IO.File]::AppendText($out);
    if($names)
    {
        write-array $wr $columnAlias;
    }
    while($r.Peek() -ge 0)
    {
        write-csv-line $wr $r.ReadLine() $indices;
    }
    $wr.Close();
}

$out = "c:\perflogs\output.csv";

trim-perflog c:\perflogs\prod_000005.csv True
trim-perflog c:\perflogs\prod_000006.csv False
trim-perflog c:\perflogs\prod_000007.csv False

My Tentative Approval of Visual Studio 2005

Despite some initial bad press, my impression so far is that Visual Studio 2005 is a pretty nice product. I would qualify that by saying that I haven't yet used it to work on a massive web project, and as we all know web projects were definitely Visual Studio 2003 at its worst. (After two years, I will NOT use Visual Studio 2003 for web projects. I refuse. They were broken. I'm 100% text editor and NAnt from the command line now.)

I am loathe to be seen as a cheerleader, and rest assured I could point to many things about Visual Studio in general and VS2005 specifically that I can't stand. But somebody out there deserves some credit for the fact that startup performance seems to have been drastically improved. In my informal test ("One Mississippi .. two Mississippi"), VS 2005 outperforms 2003's startup by an order of magnitude. Two seconds compared to thirty seconds on the same machine. That's certainly nothing to sneeze at.

You click on the icon, it opens. All software should work this way. I'm looking directly at you, OpenOffice, Trillian, and every single product developed by Adobe. While I'm on the subject, never allowing your program to close is not an acceptable solution to this problem.

I am also a fan of this:

The "close all but this" button replaces these steps:

  1. Ctrl+Shift+S
  2. Ctrl+F4, hold for five seconds
  3. Find the original file and reopen it

Nonblocking Pool Class

This is not an original idea but I thought I would post/explain it anyway. This is a generalized version of a pattern I have been using for a while. I'm not sure where I first picked it up but I've seen it used in several places.

The purpose of this class is to pool instances of a particular type in a server application. The assumptions I am making about the problem are:

  • It is both possible and worthwhile to reuse instances of a certain type. Types that may fit this criteria are large arrays of primitive types, types that hold unmanaged or scarce resources such as connections, et al. Not all types fit this criteria, obviously.
  • It is more undesirable to have a thread enter a waiting state (fail to acquire a lock, in other words) than it is to create a new instance of the type being reused. That would be the case if the instances are somewhat cheap but the average request or call time to your server is relatively long.

The nice thing about this pool class is that it handles the second case gracefully. It will reuse objects as much as possible, but it won't block a thread in the case that the attempt fails. If it didn't, you might end up introducing massive contention in your attempt to increase throughput with a different, locking pool.

The class provides very lightweight synchronization using atomic operations - there's no use of critical sections (the lock keyword).

  /// <summary>
  /// Provides and reuses objects of type <typeparamref name="T"/>.
  /// </summary>
  /// <typeparam name="T">
  /// The type that is pooled. Must provide a default constructor.
  /// </typeparam>
  public class NonBlockingPool<T>
     where T : new()
  {
     // Contains the pooled items.
     private Stack<T> _stack;

     // The maximum size of _stack.
     private int _max;

     // This reference is used to ensure that only one thread
     // calls methods on _stack at a time.
     private object _lock = new object();

     /// <summary>
     /// Gets or sets the maximum size of the pool.
     /// </summary>
     public int MaximumSize
     {
        get { return _max; }
        set { _max = value; }
     }

     /// <summary>
     /// Gets a pooled instance of type <typeparamref name="T"/>,
     /// or yields a new instance.
     /// </summary>
     public T Get()
     {
        // If two threads enter this method at the same time,
        // only one will acquire _lock (the other will be given
        // null). The caller that fails to acquire _lock will
        // be returned a new instance of T.
        T ret = default(T);
        object obj = Interlocked.Exchange(ref _lock, null);
        try
        {
           if (obj != null && _stack.Count > 0)
           {
              ret = _stack.Pop();
           }
           else
           {
              ret = new T();
           }
        }
        finally
        {
           if (obj != null)
           {
              _lock = obj;
           }
        }
        return ret;
     }

     /// <summary>
     /// Reuses an instance of type <paramref name="T"/> in a
     /// subsequent request or call whenever possible.
     /// </summary>
     public void Reuse(T t)
     {
        // If two threads enter this method at the same time,
        // only one will acquire _lock (the other will be given
        // a null reference). The instance of T provided by
        // the losing thread will just be collected and not
        // reused.
        object obj = Interlocked.Exchange(ref _lock, null);
        try
        {
           if (obj != null && _stack.Count < _max)
           {
              _stack.Push(t);
           }
        }
        finally
        {
           if (obj != null)
           {
              _lock = obj;
           }
        }
     }

     /// <summary>
     /// Constructor.
     /// </summary>
     /// <param name="max">
     /// The maximum number of instances of
     /// <typeparamref name="T"/> to hold in the pool.
     /// </param>
     public NonBlockingPool(int max)
     {
        if (max < 0)
        {
           throw new ArgumentOutOfRangeException("max");
        }
        _stack = new Stack<T>(max);
        _max = max;
     }
  }

Here's a (contrived) minimal example of a consumer of such a pool. This server class makes a context object available to each thread for the duration of each request. This object is stored in a slot unique to each thread (specified with the ThreadStaticAttribute) while a ProcessRequest function is called. The instance is returned to the pool in a finally block after that call is finished.

  public class SampleServer
  {
     [ThreadStatic]
     private static ServerContext _context;

     private NonBlockingPool<ServerContext> _pool;

     public static ServerContext Context
     {
        get { return _context; }
     }

     internal void ProcessRequest(IServerApp app)
     {
        try
        {
           _context = _pool.Get();
           app.ProcessRequest();
        }
        finally
        {
           if (_context != null)
           {
              _context.Reset();
              _pool.Reuse(_context);

              // We want the context to be collected if it isn't
              // actually reused by the pool.
              _context = null;
           }
        }
     }
  }

A more concrete example might be an IHttpModule or a remoting server channel sink. As I said once already, it's important to consider 1) the type of resource you are pooling and 2) the amount of load your application is expecting before committing yourself to a pattern such as this one.

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.

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.