Click here to Skip to main content
15,886,799 members
Articles / General Programming / Threads
Tip/Trick

Getting back on the UI thread in Silverlight

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
27 Apr 2010CPOL 10.2K  
When writing a demo for the Dutch Code-camp  I ran into issues getting back on the UI thread after calling a webservice. The call to the webservice was made from the UI thread, but the callback was made on a different thread. The System.Threading.SynchronizationContext class held the...

When writing a demo for the Dutch Code-camp  I ran into issues getting back on the UI thread after calling a webservice. The call to the webservice was made from the UI thread, but the callback was made on a different thread. The System.Threading.SynchronizationContext class held the solution.


The System.Threading.SynchronizationContext class is a base class that provides a thread-free context. It contains a read-only static property named Current, which gets the thread from which it is requested. When the current context is kept while the asynchronous call to a webservice is made, it can be used the call method in that context. The SynchronizationContext.Post can do this asynchronous, the SynchronizationContext.Send can do this synchronous.


Sample


Let me try to explain with a small sample which is taken from the code-camp demo.


The GetSearch(string searchText) method is called, which begins the call to the Bing API.



public class BingModel : IBingModel
{
    // this string is used to make the actual call to the bing API. 
    // the blancs are filled in when SearchBing method is called
    const string BingRequestURL =
        "http://api.bing.net/json.aspx?AppId={0}&Version=2.2&"
        +"Market=en-US&Query={1}&Sources=web&Web.Count={2}";
 
    // the request is kept so it can be used to handle the response
    private WebRequest request;
 
    // the SearchBing method is called from the UI thread
    //(note: //you can get your AppId at http://bing.com/developers)
    public void SearchBing(string searchText, string appId)
    {
        //the blancs are filled in  
        string requestString = 
            string.Format(BingRequestURL, 
                          appId, 
                          HttpUtility.UrlEncode(searchText),
                          20); //20 results will be givin.
        //a new request is made.
        request = HttpWebRequest.Create(requestString);
        
        //the getting of the response is started. The OnRequestCompleted 
        //method is provided so it can be called when the request is 
        //completed. The Current SynchronizationContext is provided as 
        state so it can be handled by the result.
        request.BeginGetResponse(OnRequestCompleted, 
                                 SynchronizationContext.Current);
    }
 
    //when the request is completed this method is called
    private void OnRequestCompleted(IAsyncResult ar)
    {
        //the response is extracted from the result and read thru a stream.
        var webResponse = (HttpWebResponse)request.EndGetResponse(ar);
        var response = new StreamReader(webResponse.GetResponseStream());
        
        //Because a string of Json is returned by the service, this string is 
        //parsed into a JsonObject.
        var json = JsonObject.Parse(response.ReadToEnd());
 
        //the ExtractResults method (defined below) is used to create 
        //an enumeration of the results
        IEnumerable<BingResult> ress = ExtractRestults(json);
 
        // this method (defined below) is used to fire a custom event on the UI thread
        // the state is provided as Synchronization context along with the json results
        InvokeSearchBingCompletedEvent(ar.AsyncState as SynchronizationContext, ress);
    }
    
    private void InvokeSearchBingCompletedEvent(SynchronizationContext context, 
                                                IEnumerable<BingResult> ress)
    {
        if (context != null) // just in case the context has become null somehow
            // call an anonymous method asynchronous on the context that was used to start 
            //the search
            context.Post((e) => 
                     {
                         if (SearchBingCompleted != null) 
                             //raise the event
                             SearchBingCompleted(this, new SearchBingCompletedArgs() 
                                                   {
                                                       SearchResults = ress.ToList()
                                                   }
                                 );
                     }, null);
    }
 
    // Extract search result from Json returned by Bing API  
    private static IEnumerable<BingResult> ExtractRestults(JsonValue json)
    {
        var results = json["SearchResponse"]["Web"]["Results"] as JsonArray;
 
        return from res in results
               select new BingResult()
                          {
                              Title = res["Title"],
                              Url = res["Url"]
                          };
    }
    
    // the definition of the event handler
    public event EventHandler<SearchBingCompletedArgs> SearchBingCompleted;
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Velicus B.V.
Netherlands Netherlands
Microsoft MVP Client Dev . Founder of http://StoreAppsUG.nl, the Dutch Windows Store apps and Windows Phone apps usergroup. XAML / HTML5 developer. Writer. Composer. Musician.

Twitter
@Sorskoot

Awards / Honers
• October 2010,2011,2012,2013: Awarded Microsoft Expression Blend MVP
• June 2009: Second Place in the WinPHP challenge
• February 2009: Runner-up in de Mix09 10k Challenge
• June 2008: Winner of the Microsoft expression development contest at www.dekickoff.nl

Bio
I started programming around 1992, when my father had bought our first home computer. I used GWBasic at that time. After using QBasic and Pascal for a few years I started to learn C/C++ in 1996. I went to the ICT Academy in 1997 and finnished it in 2002. Until December 2007 I worked as a 3D specialist. Besides modelling I worked on different development projects like a 3D based Scheduler and different simultion tools in C# and Java. Though out the years I've gained much experience with ASP.NET, Silverlight, Windows Phone and WinRT.

Comments and Discussions

 
-- There are no messages in this forum --