Czy otrzymałeś kiedyś taki oto błąd?
The calling thread cannot access this object because a different thread owns it.
Dzieje się tak, najczęściej wtedy, gdy próbujemy aktualizować kontrolki użytkownika z innego wątku. Taka czynność nigdy nie była dobrym pomysłem i trzeba było o tym pamiętać, jednak od wersji bodajże 2 .net Framework-a dostajemy taki wyjątek jak powyżej. Dzięki temu, nawet jeśli coś zostanie przeoczone i będziemy jednak chcieli wykonać aktualizację kontrolki użytkownika z innego wątku niż wątek interfejsu, wówczas dostaniemy ładny i zgrabny wyjątek.
Zatem jak zaktualizować kontrolkę użytkownika z innego wątku? Należy posłużyć się motodą Invoke, która wywołuje metodę w wątku właściwym dla wykonywanej operacji. W aplikacji gdzie często wykonujemy tego typu operacje, warto wykorzystać metody rozszerzające, dzięki którym możemy dodać własny plumbing do istniejących klas (nawet systemowych).
I tak w desktop info jest klasa ControlExtensions:
public static class ControlExtensions
    {
        public static void InvokeIfRequired(this Control control, Action action)
        {
            if (System.Threading.Thread.CurrentThread != control.Dispatcher.Thread)
            {
                control.Dispatcher.Invoke(action);
            }
            else
            {
                action();
            }
}
        public static void InvokeIfRequired<T>(this Control control, Action<T> action, T parameter)
        {
            if (System.Threading.Thread.CurrentThread != control.Dispatcher.Thread)
                control.Dispatcher.Invoke(action, parameter);
            else
                action(parameter);
        }
    }
Definiuje ona dwie metody rozszerzające (w parametrach metody pojawia się nagle tajemnicze słowo this) InvokeIfRequired. Dzięki nim mogę wywoływać ją bez potrzeby nadmiernego pisania kodu w każdym miejscu, które wymaga lub potencjalnie wymaga invoke-a
Jak z takiego czegoś korzystać?
 this.InvokeIfRequired((value) => seconds.Content = value, DateTime.Now.Second.ToString("00"));
W metodzie obsługującej zdarzenie Elapsed dla timera znajduje się powyższy kod, który wpisuje ilość sekund do kontrolki seconds. Proste i zgrabne.
