Cameron Albert

Ramblings of software development, games and technology.

Multi-threading in Silverlight

I’ve been working with Sockets in Silverlight over the past couple of days, in between getting the Pirates game to a workable Silverlight 2 state. One thing I came across today which sent me round and round was BeginInvoke. Anyone who has programmed multi-threaded applications in Windows has used this, mostly to execute code on the UI thread from events.

Anyway, controls in Silverlight 2 do not have the Invoke or BeginInvoke methods but controls do have a Dispatcher reference which lives in System.Windows.Threading. WPF programmers are probably already used to this but it was new for me. The Dispatcher allows you to check to see if you can access the current object on the current thread.

One thing to note about the Dispatcher is that it has a method called CheckAccess() that returns true if you can access the control on the current thread of false if you are not on the control’s thread. The CheckAccess() method is decorated with a EditorBrowsableAttribute and has it’s value set to Never. This prevents us from being able to see the method via intellisense in Visual Studio but does not prevent the method from being used. Not sure why the folks at MS wanted to hide this method and the documentation does not provide an explanation. The DependancyObject class also provides a CheckAccess method that is also hidden from the editor and just calls the Dispatcher method of the current object. Maybe it’s not documented because it might be removed in the future, it is in beta after all.

So, to sum up, if you need to be able to invoke methods on a control’s thread from a background thread you can do the following: (snippet from socket testing)

        private delegate void AppendTextDelegate(string text);
        public void AppendText(string text)
        {
            if (txtChat.CheckAccess())
            {
                // Append the message to the chat buffer.
                _content.Append(text).Append(Environment.NewLine);

                // Re-post the contents of the chat buffer to the chat text and scroll to
                // the bottom.
                txtChat.Content = _content.ToString();
                txtChat.ScrollToVerticalOffset(txtChat.ScrollableHeight);
            }
            else
            {
                txtChat.Dispatcher.BeginInvoke(new AppendTextDelegate(this.AppendText), text);
            }
        }

The _content control is just a StringBuilder that actually holds the content from the chat control.

Again, Silverlight 2 is in beta 1 so maybe this will change in the future.

Advertisements

Written by Cameron

March 14, 2008 at 8:40 pm

%d bloggers like this: