Please click this logo to help me get on their beta program:

Xobni outlook add-in for your inbox








28/10/2005

Cubism

Filed under: General — Oliver Sturm @ 5:13 pm - 2 years, 9 months ago

Remember Rubik’s cube? How about if it was… you know… LARGER? Watch this (hit Start): http://www.speedcubing.com/chris/20cube.html

23/10/2005

Receive my blog posts by email (Thanks, Scott!)

Filed under: General — Oliver Sturm @ 4:21 pm - 2 years, 9 months ago

A good hint by Scott Hanselman: FeedBlitz can publish my blog by email automatically. If you want to use it, just enter your email address in the small form on the left and hit the button, or click here.

DDD day 2 was a blast

Filed under: General, Programming, .NET — Oliver Sturm @ 2:49 pm - 2 years, 9 months ago

Developer Developer Developer day 2 was yesterday and it was fantastic. I met a bunch of people there and at the geek dinner afterwards. If you were there and we didn’t meet, bad luck… I’m sure we’ll manage next time - or you could just drop me a line. Anyway, don’t forget to leave your feedback about the event!

Calculating a running average

Filed under: General, Programming, .NET — Oliver Sturm @ 2:19 pm - 2 years, 9 months ago

In a newsgroup I replied to a question about calculating average data throughput during data reception over the network. A simple average bytes per second calculation needs only a few lines of code:

int bytesTotal = 0;
int bytesPerSecond = 0;
DateTime startTime = DateTime.Now;
	
do {
  bytesRead = receiveStream.Read( ... );
  bytesTotal += bytesRead;
  bytesPerSecond = bytesTotal / (DateTime.Now - startTime).TotalSeconds;
	
  ...
} while(bytesRead > 0);

The problem with this is that it may not render very exact values over a longer download period because actual network throughput tends to change a lot over WAN connections. It would be more accurate to work out an average over a number of most recent measured values instead. As this requires some handling of a store of measured samples, I decided to create a reusable class that can hold a number of samples in a ring buffer and calculate the current average from these samples. The class takes a weighting of each sample into account, because in scenarios like the one above it’s not always guaranteed that new samples can be measured in an exact frequency. Here’s the class:

public class RunningAverage {
  public RunningAverage(int samplesCount) {
    samples = new Sample[samplesCount];
    for (int i = 0; i < samplesCount; i++)
      samples[i] = new Sample( );
    currentSample = 0;
  }
	
  class Sample {
    public Sample( ) { }
	
    public Sample(double weighting, double measuredValue) {
      Set(weighting, measuredValue);
    }
	
    public void Set(double weighting, double measuredValue) {
      this.weighting = weighting;
      this.measuredValue = measuredValue;
      isValid = true;
    }
	
    private double weighting;
    public double Weighting { get { return weighting; } }
	
    private double measuredValue;
    public double MeasuredValue { get { return measuredValue; } }
	
    private bool isValid;
    public bool IsValid { get { return isValid; } }
  }
	
  Sample[] samples;
  int currentSample;
	
  public void AddSample(double weighting, double measuredValue) {
    samples[currentSample++].Set(weighting, measuredValue);
    if (currentSample >= samples.Length)
      currentSample = 0;
  }
	
  public double GetCurrentAverage( ) {
    double totalValue = 0;
    double totalWeighting = 0;
    foreach (Sample sample in samples)
      if (sample.IsValid) {
        totalValue += sample.MeasuredValue;
        totalWeighting += sample.Weighting;
      }
    return totalValue / totalWeighting;
  }
}

Now the receive loop above could look like this:

RunningAverage average = new RunningAverage(100);
DateTime timeStamp = DateTime.Now;
	
do {
  bytesRead = receiveStream.Read( ... );
  DateTime newTimeStamp = DateTime.Now;
  average.AddSample(newTimeStamp.TotalSeconds - timeStamp.TotalSeconds, bytesRead);
  timeStamp = newTimeStamp;
  // access average.GetCurrentAverage() if needed
	
  ...
} while(bytesRead > 0);

18/10/2005

Object pooling, part 8 - monitoring the pool’s performance

Filed under: General, Programming, .NET — Oliver Sturm @ 4:11 pm - 2 years, 9 months ago

This is the eighth article in my mini series about object pooling. Be sure to read part 1, part 2, part 3, part 4, part 5, part 6 and part 7 first.

So, although the number of downloads of the sample program hasn’t been exactly great, I’m finally continuing the series. As I said in a previous article, I’d like to factor out the resizing behaviour - but before I do that, I want to integrate functionality that’ll let me evaluate the pool’s performance with regard to resizing, so I can assess the different resizing approaches reliably.

Fortunately performance monitoring is something that needs to be integrated into the pool implementation anyway and Windows has all the tools on board. So I only need to configure a few performance counters in Windows, make sure that these counters are updated with current numbers and the Windows performance monitoring frontend is available to the user to show it all in a nice graph. (I’m sure some of you have never heard of the performance monitor application - it’s available on the Administrative tools menu and it’s called, not surprisingly, Performance.)

Here’s the download for the current version, including these changes: ObjectPooling-2.zip

And these are the changes - at the end of the pool class:

private string performanceCategoryName;
/// <summary>
/// Gets or sets a value indicating the name of the performance counter category.
/// </summary>
public string PerformanceCategoryName {
  get {
    return performanceCategoryName;
  }
  set {
    if (performanceCategoryName != value) {
      performanceCategoryName = value;
      InvalidateCounters( );
    }
  }
}
	
private string performanceCounterNamePrefix;
/// <summary>
/// Gets or sets a value indicating a prefix that is used for all the performance
/// counters of this pool instance.
/// </summary>
public string PerformanceCounterNamePrefix {
  get {
    return performanceCounterNamePrefix;
  }
  set {
    if (performanceCounterNamePrefix != value) {
      performanceCounterNamePrefix = value;
      InvalidateCounters( );
    }
  }
}
	
/// <summary>
/// Set the properties PerformanceCategoryName and PerformanceCounterNamePrefix to the values
/// passed in to the categoryName and counterNamePrefix parameters, then calls InitializeCounters().
/// </summary>
public void InitializeCounters(string categoryName, string counterNamePrefix) {
  performanceCategoryName = categoryName;
  performanceCounterNamePrefix = counterNamePrefix;
  InitializeCounters( );
}
	
private const string STR_Poolsize = "Pool size";
private const string STR_PoolsizeHelp = "The current number of poolable objects.";
private const string STR_ObjectsInUse = "Objects in use";
private const string STR_ObjectsInUseHelp =
  "The number of objects that are currently allocated to a pool user.";
	
PerformanceCounter poolSizeCounter;
PerformanceCounter inUseCounter;
	
/// <summary>
/// Initializes the performance counters according to the settings of the PerformanceCategoryName
/// and PerformanceCounterNamePrefix properties.
/// </summary>
public void InitializeCounters( ) {
  if (PerformanceCounterCategory.Exists(performanceCategoryName))
    PerformanceCounterCategory.Delete(performanceCategoryName);
	
  CounterCreationDataCollection counters = new CounterCreationDataCollection( );
	
  counters.Add(new CounterCreationData(performanceCounterNamePrefix + STR_Poolsize,
    STR_PoolsizeHelp, PerformanceCounterType.NumberOfItems32));
  counters.Add(new CounterCreationData(performanceCounterNamePrefix + STR_ObjectsInUse,
    STR_ObjectsInUseHelp, PerformanceCounterType.NumberOfItems32));
	
  PerformanceCounterCategory.Create(performanceCategoryName, "",
    PerformanceCounterCategoryType.SingleInstance, counters);
	
  poolSizeCounter = new PerformanceCounter(performanceCategoryName,
    performanceCounterNamePrefix + STR_Poolsize, false);
  inUseCounter = new PerformanceCounter(performanceCategoryName,
    performanceCounterNamePrefix + STR_ObjectsInUse, false);
}
	
void InvalidateCounter(ref PerformanceCounter counter) {
  if (counter != null) {
    counter.Dispose( );
    counter = null;
  }
}
	
void InvalidateCounters( ) {
  InvalidateCounter(ref poolSizeCounter);
  InvalidateCounter(ref inUseCounter);
}

In the ExtendPoolBy method:

  . . .
  lock (poolLock) {
    count = Math.Min(maxPoolSize - pool.Count, count);
	
    for (int i = 0; i < count; i++) {
      Slot slot = delayObjectCreation ? new Slot(objectFactory) :
        new Slot(objectFactory.CreateObject( ));
      pool.Add(slot);
    }
	
    if (poolSizeCounter != null)
      poolSizeCounter.RawValue = pool.Count;
  }
  . . .

In the ShrinkPoolBy method:

  . . .
  if (poolSizeCounter != null)
    poolSizeCounter.RawValue = pool.Count;
  . . .

… and similar code for the other counter in the GetObject and ReleaseObject methods.

17/10/2005

Specifying element order for XML serialization

Filed under: General, Programming, .NET — Oliver Sturm @ 8:18 am - 2 years, 9 months ago

And another piece of good news that had so far escaped me: in .NET 2, it’s finally possible to explicitely configure the order in which class members are serialized to XML. See the XmlElementAttribute.Order property.

14/10/2005

Serialization and optional elements

Filed under: General, Programming, .NET — Oliver Sturm @ 3:23 pm - 2 years, 9 months ago

Using a new feature called Version Tolerant Serialization in .NET 2, it becomes possible to change class definitions and still deal with old serialized data versions after an application has been updated. This is actually extremely easy to do. Consider this code:

[Serializable]
public class Test {
  string name;
  public string Name {
    get { return name; }
    set { name = value; }
  }
}

Now say you have deployed version 1 of your application with this class definition and used serialization to save instances of class Test to some kind of storage. Users of your application have megabytes of data stored away in that specific format.

Now you continue developing your application and you find the need to add properties to Test. The problem is, once you do that, you’ll no longer be able to deserialize the earlier version of the class, resulting in huge data loss for your users! Version Tolerant Serialization is the feature that comes to the rescue here. You can now define your new class version like this:

[Serializable]
public class Test {
  string name;
  public string Name {
    get { return name; }
    set { name = value; }
  }
	
  int newVal;
  [OptionalField]
  public int NewVal {
    get { return newVal; }
    set { newVal = value; }
  }
	
  bool marker;
  [OptionalField]
  public bool Marker {
    get { return marker; }
    set { marker = value; }
  }
	
  [OnDeserializing]
  void Deserializing(StreamingContext context) {
    // We get here before data is actually written to our properties
    // So we set some default values for the optional properties.
	
    newVal = 42;
    marker = false;
  }
	
  [OnDeserialized]
  void Deserialized(StreamingContext context) {
    // We get here when data has been written to all the properties
    // that were found during deserialization, which may not have been
    // all we have in case an old storage format was used.
    // So we can now analyze what's happened and fix up what's necessary.
	
    if (!marker) {
      // . . .
    }
  }
}

In many cases, dedicated fixup code may not really be necessary, but it’s certainly possible to work with older data definitions in this way, at least for most kinds of changes. There are also corresponding attributes OnSerializing and OnSerialized, in case a hook into the serialization process is needed as well.

11/10/2005

Binding.FormattingEnabled fixes two-way simple binding

Filed under: General, Programming, .NET — Oliver Sturm @ 9:22 am - 2 years, 10 months ago

This page describes a problem with .NET simple data binding - a property of a custom type couldn’t be bound correctly to the Text property of a standard TextEdit, because the internal logic would never convert the string value back to the object type. A given TypeConverter would simply be ignored in the process. The only workaround was to use the Parse event of the Binding object - not a nice way to go because the code wouldn’t be central to the class and its type converter any more.

While looking at the reasons behind this, I found a workaround for this in .NET 2: the FormattingEnabled property of the Binding object. While this is documented to do something quite different, the changed logic of the Binding.OnParse method actually checks for this parameter and the problem doesn’t show when FormattingEnabled is set to true for the binding.

It’s possible to pass true for this parameter right when creating the binding, like this:

textBox1.DataBindings.Add("Text", myObject, "MyProperty", true);

Now I’m still wondering if I’m missing something here… the original problem, although it seems to be as described on the NoiseEHC page, sounds so… stupid? And the small change in .NET 2, while it does the trick, doesn’t look like a purposeful fix of the issue to me. Hm.

6/10/2005

Electric Editing makes The Daily Grind

Filed under: General, Programming, .NET — Oliver Sturm @ 12:00 pm - 2 years, 10 months ago

Just bragging :-) Here it is: The Daily Grind 725

If you haven’t seen my Electric Editing plugin, look here.

Update: I just noticed that Jim Holmes also wrote a report about it on Visual Studio Hacks.

Horizontal lines

Filed under: General, Programming, .NET — Oliver Sturm @ 11:07 am - 2 years, 10 months ago

Just saw this post in a newsgroup about how to show the horizontal lines that Microsoft likes to use in their dialogs. A lot of people replied with ideas of using other controls, like panels, to achieve the desired effect - to me, a much simpler and more effective idea is to just create a control myself.

So, the specific style described by the OP seems to be this:

This is what you get by using a label set to a height of 2 and with a BorderStyle of Fixed3D. The OP said explicitely that this was what he wanted, which I find curious because the lines in my Word Options dialog, for instance, look quite different:

So, to account for both needs, I included the etched border as well as the single line border in my sample. I’m sure there are millions of other line styles out there, but these should be simple to include once the framework is there. Here’s the control source code:

  public enum HLineType {
    Etched,
    Single
  }
	
  public class HorizontalLine : Control {
    public HorizontalLine( ) {
      SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.FixedHeight |
        ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw |
          ControlStyles.SupportsTransparentBackColor | ControlStyles.UserPaint, true);
        lineType = HLineType.Etched;
    }
	
    public override System.Drawing.Size GetPreferredSize(Size proposedSize) {
      if (proposedSize == Size.Empty)
        return new Size(150, 10);
      return proposedSize;
    }
	
    private HLineType lineType;
    [DefaultValue(HLineType.Etched)]
    public HLineType LineType {
      get {
        return lineType;
      }
      set {
        if (lineType != value) {
          lineType = value;
            CreatePen( );
            Invalidate( );
        }
      }
    }
	
    public override Color ForeColor {
      get {
        return base.ForeColor;
      }
      set {
        base.ForeColor = value;
        CreatePen();
      }
    }
	
    Pen pen;
    void CreatePen( ) {
      if (pen != null) {
        pen.Dispose( );
        pen = null;
      }
	
      if (lineType == HLineType.Single)
        pen = new Pen(ForeColor);
    }
	
    protected override void OnPaint(PaintEventArgs e) {
      base.OnPaint(e);
      switch (lineType) {
        case HLineType.Etched:
          ControlPaint.DrawBorder3D(e.Graphics, ClientRectangle,
            Border3DStyle.Etched, Border3DSide.Top);
          break;
        case HLineType.Single:
          e.Graphics.DrawLine(pen, 0, 0, Width - 1, 0);
          break;
      }
    }
  }

This was done in VS 2005 beta 2. You might have to make minor changes for .NET 1 if needed - I’m not 100% sure about the flags in the SetStyle call, look them up if you need to.

5/10/2005

Don’t you love the web…

Filed under: General — Oliver Sturm @ 5:53 pm - 2 years, 10 months ago

… for the sheer number of opportunities it provides? Opportunities to waste lots of time with non-essential things, is what I mean.

The penguin swing

My highscore is 321. :-)

Powered by WordPress
© Copyright 2005-2008 Oliver Sturm