Eddie Garmon's Weblog

some architecture, some c#
Doh! Synced Actions and Funcs

After a little more use of the Synchronized<T>, I realized that over half the time I was 'returning true' just to satisfy Func<T, bool> when all that was really needed was an Action<T>.

Read, ReadUpgradeableToWrite, and Write are all overloaded now to take either a Action<T> or a Func<T, TReturn>.

You can get the code here.

 

More on Syncronized - upgrade reader to writer

In using my new sync wrapper to clean up a bunch of older code, I came across the need to be able to upgrade from a reader to a writer for certain operations. One example of this it to clean up expired items in my my implementation of a Cache.

protected Synchronized<Dictionary<string, ICacheItem>> _syncDictionary =
    new Synchronized<Dictionary<string, ICacheItem>>(new Dictionary<string, ICacheItem>());
...
private void PurgeExpired() {
    _syncDictionary.ReadUpgradeableToWrite((dictionary, reader) => {
        List<ICacheItem> expired = new List<ICacheItem>();
        foreach (ICacheItem cacheItem in dictionary.Values) {
            if (cacheItem.IsExpired) {
                expired.Add(cacheItem);
            }
        }
        if (expired.Count > 0) {
            reader.UpgradeToWriter();
            foreach (ICacheItem cacheItem in expired) {
                ItemRemovedInternal(cacheItem);
                dictionary.Remove(cacheItem.CacheKey);
            }
        }
        return true;
    });
}

I cleaned up the code a bit, and am making it available here. Free to use, no waranty on fitness.

 

Sync Enumerator update.

After a few more unit tests, I have fixed an issue with the GetSyncEnumerator method.

The origional had 2 issues.

  1. was that the lock was being released too soon.
  2. was that a write in the middle of a long enumeration would cause a race and/or a deadlock.

The fix was to 'write' lock for enumeration, and not to 'use' the lock, but to let the design of IDisposable on the enumerator itself work as intended.

/// <summary>
/// Gets a synchronized enumerator.
/// </summary>
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <param name="getEnumeratorFunction">The get enumerator function.</param>
/// <returns></returns>
public IEnumerator<TValue> GetSynchronizedEnumerator<TValue>(Func<T, IEnumerator<TValue>> getEnumeratorFunction) {
    Guard.ArgumentNotNull(getEnumeratorFunction, "getEnumeratorFunction");

    //cheat here and write block for enumeration.
    //otherwize a write during a long enumeration can cause a race.
    SynchronizedWriter synchronizedWriter = null;
    SynchronizedEnumerator<TValue> synchronizedEnumerator = null;
    try {
        synchronizedWriter = new SynchronizedWriter(_readerWriter);
        IEnumerator<TValue> enumerator = getEnumeratorFunction(_instance);
        synchronizedEnumerator = new SynchronizedEnumerator<TValue>(synchronizedWriter, enumerator);
        return synchronizedEnumerator;
        //When the enumerator disposes, the lock is released.
    } catch {
        if (synchronizedEnumerator != null) {
            synchronizedEnumerator.Dispose();
        } else if (synchronizedWriter != null) {
            synchronizedWriter.Dispose();
        }
        throw;
    }
}

The linked code has been updated.

Synchronization, ReaderWriterLockSlim, and Lambdas

Here is a synchronization wrapper that I wrote to wrap any object, and an implementation of a SynchronizedDictionary to show how to use it.

I offer this code as-is without any waranty to fitness, to the public domain, for any purpose you see fit.

Get a text version of this code here.

On with the show:

[UPDATE: get the code via the link, only ideas are shown below.] 

Synchronized<T>:
wraps an instance of type T.

Contains 3 functions:

  1. public TValue Read<TValue>(Func<T, TValue> readFunction)
     - inside a reader lock, executes the readFunction.
  2. public bool Write(Func<T, bool> writeFunction)
     - inside a writer lock, executes the writeFunction, which should return the success nature of the write.
  3. public IEnumerator<TValue> GetSynchronizedEnumerator<TValue>(Func<T, IEnumerator<TValue>> getEnumeratorFunction)
    - returns an enumerator wrapped in a lock that releases when it is disposed.

An example of how to use the Synchronized<T> class:

namespace SynapticPop.DataStructures.Dictionaries {
  public class SynchronizedDictionary<TKey, TValue> : IDictionary<TKey, TValue> {
    private readonly Synchronized<IDictionary<TKey, TValue>> _synchronized;

    public SynchronizedDictionary(IDictionary<TKey, TValue> dictionary) {
      _synchronized = new Synchronized<IDictionary<TKey, TValue>>(dictionary);
    }

    ...

    public int Count {
      get { return _synchronized.Read(dictionary => dictionary.Count); }
    }

    ...

    public void Add(TKey key, TValue value) {
      _synchronized.Write(dictionary => { dictionary.Add(key, value); return true; });
    }

    ...

    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() {
      return _synchronized.GetSynchronizedEnumerator(dictionary => dictionary.GetEnumerator());
    }

    ...
}

 

NUnit extensions updated for 2.2.2

I have updated the ObjectGraphAssert and TimedTest extensions for NUnit 2.2.2.

You can get them here

per the read me...

ObjectGraphAssert - allows you to compare 2 objects via all their properties, and the properties of all children in sub collections.
TimedTest - a time limited test. This helps keep your long running tests from going over a set amount of time.
There only needs to be one change in the current source of NUnit (2.2.2) to support this version of the timed test. In the TemplateTestCase class, change the method signature of doTestCase from private void to protected virtual void.

Happy Testing

Why a Timed Test in NUnit 2.2?

In response to questions about the value add of Timed Tests in NUnit:

There are several uses for timed tests, most of which fall under the umbrella of performance testing.

1) You have a piece of code/hardware that you want certain functions to complete in less than a specified amount of time. If you already have a NUnit test that exercises this functionality, all you have to do is change your [Test] attribute to a [TimedTest(time limit)] attribute an now your unit test plays 2 roles, functional unit test, and performance test.

2) Performance optimization regression testing. Say you have a segment of code that has been optimized, and has a timed test that verifies execution in less than a specified amount of time. When you run this unit test as you add to/refactor your code base, you will immediately be notified if you introduce code that has less performance than your tests allow.

3) Quickness in creating new performance tests. This is as simple as adding a new NUnit test fixture, and adding a timed test.

4) Integration of performance tests with unit tests. If you know how to write one, you know how to write the other. You don't need to integrate another testing framework to do basic performance monitoring.

5) Time limit on long running tests. Once a test times out, execution of the test stops, guaranteeing that a long running test will not slow up the build/test/deployment procedure that you have in place.

6) Add a category to all of your timed tests and with-in NUnit, you have a predefined set of performance tests to run, without checking boxes.

Also of note: I made a change to the code so that only the actual test is timed, not the setup and tear down as well. Get the updates here.

NUnit 2.2 Timed Tests...

Well I finally got around to working on some more NUnit enhancements. I have finished creating an extension for a timed test with resolution in milliseconds. I had to make several modification to NUnit.Core.TemplateTestCase to ensure code reuse.

A sample of a the new extension is shown below:

using NUnit.Extensions;
namespace NUnit.Extensions.Tests {
  [TestFixture]
  public class TimedTestFixture {
    public TimedTestFixture() {}

    [TimedTest(5000)]
    public void NapOk() {
      Thread.Sleep(2500);
    }

    [ExpectedException(typeof(TestTimeoutException))]
    [TimedTest(200)]
    public void NapTooLong1() {
      Thread.Sleep(500);
    }

    [TimedTest(2000)]
    [ExpectedException(typeof(TestTimeoutException))]
    public void NapTooLong2() {
      Thread.Sleep(500000);
    }
  }
}

If the TimedTest attrribute is defined with a negative timeout, the test is run as if it were declared as a standard Test attribute.

Get the source packaged along with my ObjectGraphAssert extension here.

Visual Studio .Net C# Item Templates Version 1.1.0

Updates were made for design time support for the 2 typed collection classes, courtesy Brendan Tompkins. I also updated the Registry class, as I found that it was not in sync with the template that I currently use.

Keep the ideas comming.

Get the Version 1.1.0 installer here.

More Visual Studio Templates (with Installer)

Due to feedback from local sources, I am urged to share my most common Visual Studio Templates.  Packaged in a MSI installer for both VS 2002 and VS 2003 are the following templates:

  • a class template
  • an enumeration template
  • an exception template
  • a nunit test template
  • a registry template
  • a typed collection template
  • a typed hashed collection template

Points of note: When creating a typed collection, or a typed hashed collection, name the class as %Type%Collection. For example, a typed collection of 'Orange' should be 'OrangeCollection' and a typed hashed collection of 'Apple' should be 'AppleCollection'. None of the other templates have any naming restrictions.

Get the installer here.

If you have ideas for other templates, please let me know and I will see about including them.

Update: These templates are in C# only at the moment. They are Project ITEM templates, not project templates, and are accessable via the Add>Add New Item context menu of the solution explorer, or the File>Add New Item menu.

Update 2: Updated typed collection to support design time environment, plus other fixes. version at link is to 1.1.0.

Cleaning the Visual Studio 2005 MRU list.

After playing with Visual Studio 2005 for a while, I have collected many a deal link in my most recently used items list. Unfortunately, VS2k5 always shows every item in the MRU list on the start page.

Well, I have updated my MRU list cleaner from 1.X to 2.0 with the November CTP. Here is what it looks like:


Get it here, includes source.

 

More Posts Next page »