Archive for January, 2008

SyncHashtable is not enumerable…

January 19, 2008

One of the things I really like about working on Mole is that I get to debug some obscure issues that I haven’t come across before. Today, Karl mentioned that there was an issue when dealing with collections – specifically with a synchronized hashtable. Mole was dealing with collections using one of the base collection interfaces – ICollection. He fixed the issue correctly by iterating the IDictionaryEnumerator you get from the IDictionary implementations of a hashtable but I wanted to see what was go on so I decided to look into this further.

The problem can be reproduced with the following snippet:

Hashtable ht = new Hashtable();

Hashtable syncedTable = Hashtable.Synchronized(ht);

IEnumerator enumerator = ((ICollection)syncedTable).GetEnumerator();

Or more likely it would be something like this:

Hashtable ht = new Hashtable();

Hashtable syncedTable = Hashtable.Synchronized(ht);

syncedTable.Add(“Foo”, “Bar”);

EnumerateCollection(syncedTable);

Where EnumerateCollection was something like the following:

private void EnumerateCollection(IEnumerable enumerable)

{

    foreach (object value in enumerable)

    {

        // do something

    }

}

I took at a look at MS’ code for the Hashtable class using Reflector and there is an obvious bug in their implementation. I did a quick internet search and it seems like people have been bitten by this same issue for a while so its hard to believe that it still exists within the framework today. In case anyone encounters the issue, I’ll explain what’s going on.

Hashtable implements the IDictionary interface which derives from ICollection and therefore IEnumerable. Both IDictionary and IEnumerable define a GetEnumerator method. For IDictionary this returns an IDictionaryEnumerator and for IEnumerable this returns an IEnumerator. Hashtable’s implementation of the IDictionary method is a public virtual GetEnumerator method. Its implementation of the IEnumerable method is an explicit implementation of the interface method.

e.g. IEnumerator IEnumerable.GetEnumerator();

The Hashtable class exposes a public static method named Synchronize that is supposed to take a hashtable and return a thread safe hashtable. There are actually flaws in the thread safety aspect of the implementation but that is another matter outside the issue we were dealing with. The Synchronize methods returns an instance of a private nested class named SyncHashtable which derives from Hashtable and is basically a thin wrapper around the Hashtable you pass to the Synchronize method. SyncHashtable overrides the virtual methods on the base Hashtable class and attempts to make dealing with the hashtable thread safe by using locks around edits.

SyncHashtable correctly overrides the public virtual GetEnumerator method and returns the IDictionaryEnumerator of the hashtable its wrapping. However, and herein lies the problem, it does not reimplement the IEnumerable.GetEnumerator method. Therefore, you get the base Hashtable’s implementation which returns an enumerator (HashtableEnumerator) for the SyncHashtable itself. This enumerator class assumes that the buckets member variable of the Hashtable it is to enumerate is non-null but the SyncHashtable specifically uses an overload of the Hashtable constructor that does not initialize this member (and others normally initialized for a Hashtable). It makes sense that they would not want to initialize these values since the SyncHashtable doesn’t store its own values – remember its just a thin wrapper around the Hashtable you provided to the Synchronize method – but then they should have reimplemented the IEnumerable.GetEnumerator method.

So if you’re writing any code that enumerates collections using the IEnumerable interface (directly or indirectly) with an object where you’re not in control of the source, you may want to consider dealing with the IDictionary’s enumerator first.

So you could fix the EnumeratorCollection method above as follows:

private void EnumerateCollection(IEnumerable enumerable)

{

    IEnumerator enumerator;

 

    // SyncHashtable has a bug where its IEnumerable

    // returns an enumerator whose ctor causes a crash.

    // instead, we can get around the problem using its 

    // IDictionary.GetEnumerator impl

    Hashtable table = enumerable as Hashtable;

 

    if (null != table)

        enumerator = table.GetEnumerator();

    else

        enumerator = enumerable.GetEnumerator();

 

    while (enumerator.MoveNext())

    {

        object value = enumerator.Current;

 

        // do something

    }

}

Compare Property & Field Values with Mole

January 15, 2008

As seems to happen with Mole, a suggestion quickly snowballed into a feature implementation. Mole now has the ability to save the members (properties/fields) of the selected element to an xml file and allow you to load that xml file back in to allow property comparison. This will be extremely helpful when you’re trying to debug a problem where something works for one element but doesn’t for another instance. There’s even an option to filter out members with the same value so you can see just the properties that differ.

 You can download the latest version here.

In addition, Karl has been posting some videos on YouTube that show how to use Mole. You can view those videos here.

Editing Properties and Fields with Mole

January 1, 2008

When debugging there are often times when you need to manipulate the value of a property or field within the watch window. Mole is a great visualizer that lets inspect the properties/fields of other objects in the visual/logical tree but if you saw something that needed to be changed, you would have to come out of the visualizer, change the value (assuming you could easily write the code necessary in the watch window Name column to locate the appropriate object) and then continue debugging.

Well, one of the things that I really wanted to see in Mole was editing capability similar to that of Snoop so we took the time and added it in. I wrote the editing infrastructure making use of .NET’s TypeConverters and Karl wrote the editors making it easy to edit common data types like fonts, colors, enums, etc. You can check it out here.

Note, there are some limitations to what can be done. For example, you can’t create new instances of classes as you might be able to do with the watch window. Since we’re using typeconverters, the editing is limited to the typeconverter associated with the property/field type. Maybe this is something we can look to add in a future version.


Follow

Get every new post delivered to your Inbox.