I just began my first development with Silverlight for windows mobile 7 and I rapidly ran into one of the most famous newbie mistake: the misuse of the UI threading.

At first I just wanted to make a basic app that load a webpage and display the string content. Thus a simple default project in which I add a simple text block is just enough:

A basic text block into the default layout
A basic text block into the default layout

My view is ready; let’s add some code to it. I just add ContentPanel_Loaded event and insert a simple http request that will load a webpage and update the text label:

[csharp]
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
}

private void ContentPanel_Loaded(object sender, RoutedEventArgs e)
{
// instantiate the web client
var client = new RestClient("http://google.fr");
// make the asynchronous request, assign the result to the textblock
client.ExecuteAsync(new RestRequest(Method.GET),
r => textBlock1.Text = r.Content);
}
}
[/csharp]

Actually I used the RestSharp library (RestSharp website) in order to easily make a asynchronous request. The important thing is that I threaded my request and when I get the result I display it in the textblock.

At first, it looks like it could work well but… when you run it throw a UnathorizedAccessException (“Invalid cross-thread access”). Basic mistake.

We need to know that Silverlight support multithreading but reserve the UI access to one specific thread. When we made the asynchronous request, it was in another thread that has no right to update the UI, thus we got the previous exception.

In order to fix this, we need to access to the authorized thread and make it update the textBlock.

[csharp]
private void ContentPanel_Loaded(object sender, RoutedEventArgs e)
{
var client = new RestClient("http://google.fr");
client.ExecuteAsync(
new RestRequest(Method.GET),
r =>
{
// access the dispatcher and give the action
Dispatcher.BeginInvoke(
new Action<string>(UpdateTextBlock),
r.Content);
});
}

// function that update the textBlock
void UpdateTextBlock(string result)
{
textBlock1.Text = result;
}
[/csharp]

Now, instead of directly update the textBlock, we tell the dispatcher to call the UpdateTextBlock function with the request string result. The dispatcher will automatically ask the UI thread to call the function, thus it is executed by the right thread.

The result in the emulator
The result in the emulator

You can find more information about this subject here: Dispastcher documentation.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s