Beating the Disposal Blues

Author John Hatton | 18.01.2008 | Category Developers

This blog is largely a note to my future self, as I know I’ll be here again, and hopefully will google for the right terms to find this entry.

I had just added our standard code to ensure that a control was disposed of properly:

if (!this._disposed)
throw new InvalidOperationException("Disposed not explicitly called on " GetType().FullName ".");

Using Resharper’s Unit Test Runner, all my tests passed. I checked it in, and fired up the build machine. The build uses NUNIT console to run its tests; they all passed there, too, but the build failed because this code was throwing this InvalidOperationException all over!

Notice, the key problem here is that this exception is thrown on the finalization thread, at indeterminate times. So ReSharper might not notice it at all, and no test runner really knows which test caused it. Even with Nunit, the message was listed under the wrong test method a couple of times; this is quite understandable; suddenly this exception comes through, how’s the test runner supposed to know that the fault was actually 8 tests back? If you have a thousand or so unit tests, it can be tough to figure out which one forgot to dispose of the object.

I got out of this mess by storing the stack trace, at the time of construction, with the object:

public DetailList()
_stackAtConstruction = new StackTrace();

Then, in the finalizer,  I just cough that back up:

if (!this._disposed)
string trace = "Was not recorded.";
if (_stackAtConstruction != null)
trace = _stackAtConstruction.ToString();
throw new InvalidOperationException("Disposed not explicitly called on " GetType().FullName ". Stack at creation was " trace);



Using WeSay from other applications

Author John Hatton | 16.01.2008 | Category WeSay

Recently, we were asked to make a way for a user of a translation program to make use of WeSay, without leaving the program they’ve been trained on. The native speaker-user will want to:

  • See which words are missing from the dictionary, and add them along with a definition.
  • Jump into the entry screen for a word in WeSay to do more advanced editing.
  • Point to a word and see a list of similar words they might choose instead (thesaurus lookup).

A linguist working with the group will want to:

  • Click on an unfamiliar word and see the full dictionary article for it.

If the language has any affixation, both users will need to be able to:

  • see a list of entries, ordered by how similar their spellings are to the word be investigated.
  • find words based on their inflected/derived forms, not just by the citation form in the dictionary.
  • add variants to the word so that it is clear that this form is covered by the dictionary, and make it easier to lookup next time.

The first round of this work is now available for other application developers to use (the italicized bullet items above will come in some future version).

To help developers add these features to their programs, I’ve built a little sample application so they can see what’s possible and how to do it. Here’s a little crummy video showing it:

A few technical details for developers

Currently, I’ve implemented support for .net applications to make use of these services. But support via any language, via xml-rpc, should be easy to add when needed. All .net applications need to do is get our Palaso library and use the DictionaryAccessor class. You currently need to tell it where on the user’s machine to find WeSay, and where the dictionary is that you’ll be accessing.

Here’s some code to show what it takes add this ability to a .net application:

Getting some HTML of matching entries to show in a WebBrowser control

DictionaryAccessor dictionary = new DictionaryAccessor("c:docsnoosupunoosupu.lift", "c:program fileswesaywesapp.exe");

string[] forms;

string[] ids;

dictionary.GetMatchingEntries(writingSystemIdForWords, “foobar”,

       FindMethods.Exact, out ids, out forms);

string html = dictionary.GetHtmlForEntries(ids);

Adding a new word

dictionary.AddEntry(writingSystemIdForWords, wordBox.Text,


                    writingSystemIdForWords, exampleBox.Text);

Ok, so you get the idea that this will be a very easy service to add to your .net program.

A plug here for .net 3’s WCF (Windows Communication Framework), which made implementing this a very nice experience. I actually used Mono’s Olive implementation of it, to be sure we can do this on Linux.

Solid Released

Author cambell | 16.01.2008 | Category Solid

A new release of Solid is now available for download.

A couple of minor issues have been fixed relating to inference when more than one parent node is inferred and also navigation using the error report.

Full details of changes made in this release are available on the project site:

7 Ultimate