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
{
const string BingRequestURL =
"http://api.bing.net/json.aspx?AppId={0}&Version=2.2&"
+"Market=en-US&Query={1}&Sources=web&Web.Count={2}";
private WebRequest request;
public void SearchBing(string searchText, string appId)
{
string requestString =
string.Format(BingRequestURL,
appId,
HttpUtility.UrlEncode(searchText),
20);
request = HttpWebRequest.Create(requestString);
state so it can be handled by the result.
request.BeginGetResponse(OnRequestCompleted,
SynchronizationContext.Current);
}
private void OnRequestCompleted(IAsyncResult ar)
{
var webResponse = (HttpWebResponse)request.EndGetResponse(ar);
var response = new StreamReader(webResponse.GetResponseStream());
var json = JsonObject.Parse(response.ReadToEnd());
IEnumerable<BingResult> ress = ExtractRestults(json);
InvokeSearchBingCompletedEvent(ar.AsyncState as SynchronizationContext, ress);
}
private void InvokeSearchBingCompletedEvent(SynchronizationContext context,
IEnumerable<BingResult> ress)
{
if (context != null)
context.Post((e) =>
{
if (SearchBingCompleted != null)
SearchBingCompleted(this, new SearchBingCompletedArgs()
{
SearchResults = ress.ToList()
}
);
}, null);
}
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"]
};
}
public event EventHandler<SearchBingCompletedArgs> SearchBingCompleted;
}
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.