It’s often very tempting to write your own version of ObservableCollection to accomodate cross-thread calls. However, this is not a very good idea, because you never know what your usage scenario might be. For example, I had to create a binding to an ObservableCollection with set semantics (i.e., duplicates are not allowed) in order to get SQL Server Management Objects to periodically scan the network for SQL Server instances. Even though I already had a MyObservableCollection class ready, it didn’t work for me because I needed to get a result from the conditional insert method, indicating whether it actually succeeded.

As always, I got tempted to use the PostSharp aspect to make the call async and to handle errors. However, what I ended up doing is isolating my async code from the code that still had to happen in the UI thread. The end result – another rather ugly call on the Dispatcher:

[WorkerThread, ExceptionDialog]
private void LoadDatabases()
{
  bool added;
  do
  {
    added = false;
    foreach (string db in State.FindDatabases())
    {
      added = (bool)Dispatcher.Invoke(
        (Func<string, bool>) delegate(string s)
        {
          bool a = false;
          if (!Databases.Contains(s))
          {
            a = true;
            Databases.Add(s);
          }
          return a;
        }, db);
      }
  } while (added);
}

Code like this makes me want to be an Erlang programmer.