May 2004 - Posts

And I'm TechEd bound. The new tablet has VPC images waiting to be filled up. I can finally blog about VS Team System, the Information Bridge Framework looks nifty from the outside (the download page has a lucid 3-line description, skip the fluff), and I can't wait for TechEd Bingo. Marcie's even hosting a Birds of a Feather session (Wednesday 7:00 PM- 8:00 PM, 14A). It promises to be a fun week. Hope to meet a bunch of you there!

One early disappointment: a voucher for Yukon? I can't install a voucher. I can't test row-level cache invalidation with a voucher. Next thing you'l tell me ObjectSpaces is slipping again. What's that? Damn.

One early surprise: CommNet is actually useful this year. I just finished planning a good chunk of my waking hours in San Diego, and it didn't involve thumbing through a booklet with 6-pt text.

There remains confusion over what to inherit from when creating custom exceptions. Best-practises opinions range from the .NET Framework documentation: “If you are designing an application that needs to create its own exceptions, derive from the ApplicationException class,” through to the .NET Framework Standard Library Annotated Reference (Vol.1): “You should not define new exception classes derived from ApplicationException; use Exception instead. In addition, you should not write code that catches ApplicationException.” So which is it?

System.Exception
If extending the base exception class with additional members, inherit from System.Exception. The name of such inherited classes should end with “Exception.”

Properly, System.Exception should have been declared as abstract with a recommendation to be inherited only by concrete exception classes. Doing so would have avoided the question of which to use right from the start, and would have also helped MS with versioning. However, since things are what they are, in this situation it makes sense to inherit and extend System.Exception. The rule to tend towards a flat hierarchy wins. Inherit from System.Exception when creating a class which adds members.

System.ApplicationException
Applications often provide their own custom exception types (e.g. CmsException, SharePointException) which do not add properties or methods, but simply subclass System.ApplicationException with a new name. If more detailed expections are required for the application, they will then inherit from this base class. This makes it convenient to throw application-specific exceptions that can be identified distinctly inside a try-catch block. When doing the same for your own applications, inherit from System.ApplicationException.

For both System.Exception and System.Application, the rules are consistent in this way: they work with the Framework as it is, not as we would like it to be. Since ApplicationException exists and is in common use, it would be a deviation to derive application-specific exceptions directly from System.Exception. So while you still won't catch ApplicationException directly, you should certainly catch its descendants.

System.SystemException
The difference between ApplicationException and SystemException is that SystemExceptions are thrown by the CLR, and ApplicationExceptions are thrown by Applications. For example, SqlException inherits from SystemException. Included here to make this list complete, there should not be any circumstances where one would need to inherit from SystemException.

These rules are a dump of the model as it exists in my head after a few months of picking up bits and pieces from the various sources. It isn't gospel, but it works for me. Always subject to improvement, feel free to comment.

Further references:
DotNetJunkies article which covers some of this: .NET Anatomy - Structured Exception Handling in .NET
How to Rethrow an Exception Correctly
Design Guidelines Update: Exception Message Guidelines
Exception Management Application Block
Rich Custom Error Handling

Posted by erobillard | 6 comment(s)
Filed under: ,

Random number generators written in code (or any deterministic algorithm) aren't really random. You could go as far as to say that unless based on nondeterministic events at a quantum level, there will (theoretically) be a way of predicting the next number in a series. Taking it this far might sound silly, but it gets the point across.

Random number algorithms are good at generating a series of numbers which appear random. All start with a seed value n, where n is really random number #1. n then becomes the seed for the next number in the series (random number #2), or n.Next. Start two or more generators with the same seed, and each will generate the same series of numbers.

Random number generators based in hardware (e.g. on a PCI card) use natural phenomenon like EMF noise from a crystal. Where atomic clocks measure time by measuring events from materials with regular, predictable properties of decay or emission, hardware number generators just use materials which would make for awful clocks; the unpredictability of the material makes it a good random number generator. But let's get back to .NET and stuff you can actually use.

.NET provides a Random object. It uses a deterministic algorithm. Seed it twice with the same value and Random.Next will deliver the same output. If you create a Random object every time you need a single random number, you're not taking advantage of the algorithm, you're creating instances, not a series. Using the system clock as a seed value is fine -- numbers will appear random to you -- until you create two Random objects during the same clock tick. That didn't happen a few years ago, but today machines work fast enough that this is an issue.

To solve the problem, take advantage of the fact that Random is good at producing a series. Use the same instance of Random from call to call, number to number, and your n.Next will churn out reasonably random series. How do you do that? Cache it! The following chunk of code returns a Random object ready for calling .Next, and caches it from request to request:

/// <summary> 
/// Get a Random object which is cached between requests.
/// The advantage over creating the object locally is that the .Next
/// call will always return a new value. If creating several times locally
/// with a generated seed (like millisecond ticks), the same number can be
/// returned.
/// </summary>
/// <returns>A Random object which is cached between calls.</returns>
public static Random GetRandom(int seed)
{
Random r = (Random)HttpContext.Current.Cache.Get("RandomNumber");
if (r == null) {
if (seed == 0)
r = new Random();
else r = new Random(seed);
HttpContext.Current.Cache.Insert("RandomNumber",r);
}
return r;
}

/// <summary>
/// GetRandom with no parameters.
/// </summary>
/// <returns>A Random object which is cached between calls.</returns>
public static Random GetRandom()
{
return GetRandom(0);
}

And this is the code that calls it:

Random r = GetRandom(); // Produce a number from 00000 through 99999 
lock (r)
{
String myNumber = r.Next(0,99999).ToString("00000");
}

[Update 2004-05-06: Added a lock {} around the code which executes r.Next() according to the recommendation in Brad Abrams weblog.]

[Update 2005-07-05: Cleaned up the text slightly and double-checked that improvements from the comments are in there. This entry now has over 32,000 hits now, may as well make it the last stop you need to make.]

Posted by erobillard | 14 comment(s)
Filed under: ,
More Posts