<?xml version="1.0" encoding="UTF-8" ?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="it-IT"><title type="html">grava</title><subtitle type="html" /><id>http://blog.avanadeadvisor.com/blogs/grava/atom.aspx</id><link rel="alternate" type="text/html" href="http://blog.avanadeadvisor.com/blogs/grava/default.aspx" /><link rel="self" type="application/atom+xml" href="http://blog.avanadeadvisor.com/blogs/grava/atom.aspx" /><generator uri="http://communityserver.org" version="2.0.60217.2664">Community Server</generator><updated>2008-07-15T04:17:59Z</updated><entry><title>SL Sync just one test solution</title><link rel="alternate" type="text/html" href="http://blog.avanadeadvisor.com/blogs/grava/archive/2008/08/29/11654.aspx" /><id>http://blog.avanadeadvisor.com/blogs/grava/archive/2008/08/29/11654.aspx</id><published>2008-08-29T09:28:23Z</published><updated>2008-08-29T09:28:23Z</updated><content type="html">&lt;p&gt;A little solution for seeing in action what we've discussed&amp;#160; &lt;a href="http://blog.avanadeadvisor.com/blogs/grava/archive/2008/08/28/11652.aspx"&gt;here&lt;/a&gt;:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://code.google.com/p/syncsl/" href="http://code.google.com/p/syncsl/"&gt;http://code.google.com/p/syncsl/&lt;/a&gt;&lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:10eaaa15-f748-460e-9688-055457170715"&gt;Technorati Tag: &lt;a href="http://technorati.com/tags/Silverlight" rel="tag"&gt;Silverlight&lt;/a&gt;,&lt;a href="http://technorati.com/tags/wcf" rel="tag"&gt;wcf&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blog.avanadeadvisor.com/aggbug.aspx?PostID=11654" width="1" height="1"&gt;</content><author><name>grava</name><uri>http://blog.avanadeadvisor.com/members/grava.aspx</uri></author></entry><entry><title>Resyncing the APM model of Silverlight</title><link rel="alternate" type="text/html" href="http://blog.avanadeadvisor.com/blogs/grava/archive/2008/08/28/11652.aspx" /><id>http://blog.avanadeadvisor.com/blogs/grava/archive/2008/08/28/11652.aspx</id><published>2008-08-28T09:27:00Z</published><updated>2008-08-28T09:27:00Z</updated><content type="html">&lt;H4&gt;The Story&lt;/H4&gt;
&lt;P&gt;Often ideas are more powerful that tools, well my boss &lt;STRONG&gt;Roberto Chinelli&lt;/STRONG&gt; (&lt;A href="http://www.avanade.com/people/expert_detail.aspx?expertid=86" target=_blank&gt;avanade experts page&lt;/A&gt; - &lt;A href="http://www.linkedin.com/pub/0/246/045" target=_blank&gt;Linkedin profile&lt;/A&gt;) had one of those ideas!&lt;/P&gt;
&lt;P&gt;His passion for technology impress me everyday, and here are the results.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;...&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Last months have been hard months, smuggling around to find some usuful tip to resync the programming model in silverlight 2b2. &lt;BR&gt;Well, we didn't find yet the motivation that pushed SL team to "remove" synchronous programming model from Silverlight, but we really need it, we're trying to implement an automatic tool that translate an application from anonther language to C# Code behind of Silverlight User Controls. Well it isn't an easy job, we know, but Asynchronous Programming Model (APM from now) wouldn't been good news for us. &lt;/P&gt;
&lt;H4&gt;The Problem&lt;/H4&gt;
&lt;P&gt;Let's make a first simple example. For saving data we implemented a WCF service, hosted in the same web app that hosts SL pages, once implemented and deployed, service is available to our Silverlight application, and let's see how we have to use it due to APM. &lt;/P&gt;
&lt;DIV&gt;
&lt;DIV&gt;&lt;PRE&gt;&lt;SPAN&gt;   1:&lt;/SPAN&gt; &lt;SPAN&gt;protected&lt;/SPAN&gt; &lt;SPAN&gt;void&lt;/SPAN&gt; btn_Click(&lt;SPAN&gt;object&lt;/SPAN&gt; sender, RoutedEventArgs e) &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   2:&lt;/SPAN&gt; {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   3:&lt;/SPAN&gt;     &lt;SPAN&gt;// service proxy initialization&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   4:&lt;/SPAN&gt;     ServiceApplication client = &lt;SPAN&gt;new&lt;/SPAN&gt; ServiceApplication();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   5:&lt;/SPAN&gt;     client.OnSaveDataCompleted += OnSaveDataCompleted;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   6:&lt;/SPAN&gt;     client.SaveData(data);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   7:&lt;/SPAN&gt; }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   8:&lt;/SPAN&gt; &lt;SPAN&gt;protected&lt;/SPAN&gt; &lt;SPAN&gt;void&lt;/SPAN&gt; OnSaveDataCompleted(...)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   9:&lt;/SPAN&gt; {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  10:&lt;/SPAN&gt;     &lt;SPAN&gt;if&lt;/SPAN&gt; (e.Error == &lt;SPAN&gt;null&lt;/SPAN&gt;) &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  11:&lt;/SPAN&gt;     {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  12:&lt;/SPAN&gt;         &lt;SPAN&gt;// Object have been saved&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  13:&lt;/SPAN&gt;         &lt;SPAN&gt;// show message to user notifying the data saved&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  14:&lt;/SPAN&gt;     }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  15:&lt;/SPAN&gt;     &lt;SPAN&gt;else&lt;/SPAN&gt; &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  16:&lt;/SPAN&gt;     {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  17:&lt;/SPAN&gt;         &lt;SPAN&gt;// Show Exception message to the user (e.g. in a popup canvas)&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  18:&lt;/SPAN&gt;     }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  19:&lt;/SPAN&gt; }&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;Well, no problem for that, the APM gives the developer the ability to work with time consuming methods witouth hanging the UI ... but let's think to a simple example in which we have to wait for the response, let's think to button that shuold save data to db that executes these operations: &lt;BR&gt;1) Get data from db &lt;BR&gt;2) checks result &lt;BR&gt;3) if result == "OK " saves data into db &lt;BR&gt;this use case should be written with this code snippet with apm: &lt;BR&gt;&lt;/P&gt;
&lt;DIV&gt;
&lt;DIV&gt;&lt;PRE&gt;&lt;SPAN&gt;   1:&lt;/SPAN&gt; &lt;SPAN&gt;protected&lt;/SPAN&gt; &lt;SPAN&gt;void&lt;/SPAN&gt; btn_clic(&lt;SPAN&gt;object&lt;/SPAN&gt; sender, RoutedEventArgs e)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   2:&lt;/SPAN&gt; {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   3:&lt;/SPAN&gt;     &lt;SPAN&gt;// service proxy initialization&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   4:&lt;/SPAN&gt;     ServiceApplication client = &lt;SPAN&gt;new&lt;/SPAN&gt; ServiceApplication();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   5:&lt;/SPAN&gt;     client.GetDataComplete = OnGetDataComplete;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   6:&lt;/SPAN&gt;     client.GetDataAsync(id);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   7:&lt;/SPAN&gt; }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   8:&lt;/SPAN&gt; &lt;SPAN&gt;protected&lt;/SPAN&gt; &lt;SPAN&gt;void&lt;/SPAN&gt; OnDbLookupComplete(...) &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   9:&lt;/SPAN&gt; {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  10:&lt;/SPAN&gt;     &lt;SPAN&gt;if&lt;/SPAN&gt; (e.Error == &lt;SPAN&gt;null&lt;/SPAN&gt;)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  11:&lt;/SPAN&gt;     {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  12:&lt;/SPAN&gt;         &lt;SPAN&gt;// GetData, read data returned from method&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  13:&lt;/SPAN&gt;         &lt;SPAN&gt;// Check Results&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  14:&lt;/SPAN&gt;         &lt;SPAN&gt;if&lt;/SPAN&gt; (e.Result.Equals(&lt;SPAN&gt;"OK"&lt;/SPAN&gt;))&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  15:&lt;/SPAN&gt;         {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  16:&lt;/SPAN&gt;             ServiceApplication client = &lt;SPAN&gt;new&lt;/SPAN&gt; ServiceApplication();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  17:&lt;/SPAN&gt;             client.SaveDataComplete = OnSaveDataComplete;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  18:&lt;/SPAN&gt;             client.SaveDataAsync(id,data);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  19:&lt;/SPAN&gt;         }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  20:&lt;/SPAN&gt;     }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  21:&lt;/SPAN&gt;     &lt;SPAN&gt;else&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  22:&lt;/SPAN&gt;     {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  23:&lt;/SPAN&gt;         &lt;SPAN&gt;// getData returned an error&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  24:&lt;/SPAN&gt;         &lt;SPAN&gt;// notify user with the exception message&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  25:&lt;/SPAN&gt;         &lt;SPAN&gt;// no save&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  26:&lt;/SPAN&gt;     }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  27:&lt;/SPAN&gt; }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  28:&lt;/SPAN&gt; &lt;SPAN&gt;protected&lt;/SPAN&gt; &lt;SPAN&gt;void&lt;/SPAN&gt; OnSaveDataCompleted(...)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  29:&lt;/SPAN&gt; {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  30:&lt;/SPAN&gt;     &lt;SPAN&gt;if&lt;/SPAN&gt; (e.Error == &lt;SPAN&gt;null&lt;/SPAN&gt;) &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  31:&lt;/SPAN&gt;     {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  32:&lt;/SPAN&gt;         &lt;SPAN&gt;// no Exceptions, saving data was OK !&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  33:&lt;/SPAN&gt;         &lt;SPAN&gt;// notify user&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  34:&lt;/SPAN&gt;     }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  35:&lt;/SPAN&gt;     &lt;SPAN&gt;else&lt;/SPAN&gt; &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  36:&lt;/SPAN&gt;     {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  37:&lt;/SPAN&gt;         &lt;SPAN&gt;// exception.message shown to the user ...&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  38:&lt;/SPAN&gt;     }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  39:&lt;/SPAN&gt; }&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;You can easily see that well, everything probably will run without problems but we had to write a callback for each "atomic" Db Statement. In a synchronous environment we probably wrote something like: &lt;BR&gt;&lt;/P&gt;
&lt;DIV&gt;
&lt;DIV&gt;&lt;PRE&gt;&lt;SPAN&gt;   1:&lt;/SPAN&gt; &lt;SPAN&gt;protected&lt;/SPAN&gt; &lt;SPAN&gt;void&lt;/SPAN&gt; btn_clic(&lt;SPAN&gt;object&lt;/SPAN&gt; sender, RoutedEventArgs e)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   2:&lt;/SPAN&gt; {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   3:&lt;/SPAN&gt;     ServiceApplication client = &lt;SPAN&gt;new&lt;/SPAN&gt; ServiceApplication();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   4:&lt;/SPAN&gt;     &lt;SPAN&gt;string&lt;/SPAN&gt; result = client.GetData(id);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   5:&lt;/SPAN&gt;     &lt;SPAN&gt;if&lt;/SPAN&gt; (id == &lt;SPAN&gt;"OK"&lt;/SPAN&gt;)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   6:&lt;/SPAN&gt;     {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   7:&lt;/SPAN&gt;             client.SaveData(id, data);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   8:&lt;/SPAN&gt;     } &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   9:&lt;/SPAN&gt;     &lt;SPAN&gt;else&lt;/SPAN&gt; &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  10:&lt;/SPAN&gt;     {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  11:&lt;/SPAN&gt;         &lt;SPAN&gt;//notify error&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  12:&lt;/SPAN&gt;     }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  13:&lt;/SPAN&gt; }&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;Yes, it's a simplified example, without exception handling etc, etc ... and for sure we can (if not handled with care) run into starvation and Blocked UI in our app ... &lt;BR&gt;Well here was our problem, translating something (written in a different programming language) like: &lt;BR&gt;x = getFormDB(data) &lt;BR&gt;if (x) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = savedata(data, input) &lt;BR&gt;else &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; err &lt;BR&gt;into c# with a Language Parser, should give us some headhache with the APM, but some less with the Synchronous way ...&lt;/P&gt;
&lt;H4&gt;Our "Sync" Service Proxy Wrapper&lt;/H4&gt;
&lt;P&gt;Working hard on it we were able to write down a "sync" proxy (notice the ""), it's a wrapper class for the proxy created from visual studio when adding service references. It "simulate" the synchoronous model, it's not sinchronous for real. &lt;BR&gt;First of all we wrote an implementation for a Syncrhonization Object: &lt;BR&gt;&lt;/P&gt;
&lt;DIV&gt;
&lt;DIV&gt;&lt;PRE&gt;&lt;SPAN&gt;   1:&lt;/SPAN&gt; &lt;SPAN&gt;public&lt;/SPAN&gt; &lt;SPAN&gt;class&lt;/SPAN&gt; CallSynchronization&amp;lt;T&amp;gt; &lt;SPAN&gt;where&lt;/SPAN&gt; T : System.ComponentModel.AsyncCompletedEventArgs&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   2:&lt;/SPAN&gt; {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   3:&lt;/SPAN&gt;     AutoResetEvent sync = &lt;SPAN&gt;new&lt;/SPAN&gt; AutoResetEvent(&lt;SPAN&gt;false&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   4:&lt;/SPAN&gt;     T result;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   5:&lt;/SPAN&gt;     &lt;SPAN&gt;public&lt;/SPAN&gt; &lt;SPAN&gt;void&lt;/SPAN&gt; Completed(T result)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   6:&lt;/SPAN&gt;     {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   7:&lt;/SPAN&gt;         &lt;SPAN&gt;this&lt;/SPAN&gt;.result = result;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   8:&lt;/SPAN&gt;         sync.Set();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   9:&lt;/SPAN&gt;     }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  10:&lt;/SPAN&gt;     &lt;SPAN&gt;public&lt;/SPAN&gt; &lt;SPAN&gt;bool&lt;/SPAN&gt; Wait()&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  11:&lt;/SPAN&gt;     {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  12:&lt;/SPAN&gt;         &lt;SPAN&gt;return&lt;/SPAN&gt; sync.WaitOne();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  13:&lt;/SPAN&gt;     }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  14:&lt;/SPAN&gt;     &lt;SPAN&gt;public&lt;/SPAN&gt; T Result { get { &lt;SPAN&gt;return&lt;/SPAN&gt; result; } }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  15:&lt;/SPAN&gt; }&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;With a "classic" serviceApplication ("MyServiceClient") automatically generated from the "Add service reference command", let's start with writing down the SyncProxy: &lt;BR&gt;&lt;/P&gt;
&lt;DIV&gt;
&lt;DIV&gt;&lt;PRE&gt;&lt;SPAN&gt;   1:&lt;/SPAN&gt; &lt;SPAN&gt;public&lt;/SPAN&gt; &lt;SPAN&gt;class&lt;/SPAN&gt; MyServiceClientSync&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   2:&lt;/SPAN&gt; {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   3:&lt;/SPAN&gt;     &lt;SPAN&gt;// async proxy&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   4:&lt;/SPAN&gt;     MyServiceClient client;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   5:&lt;/SPAN&gt;     &lt;SPAN&gt;public&lt;/SPAN&gt; MyServiceClientSync() &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   6:&lt;/SPAN&gt;     {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   7:&lt;/SPAN&gt;         client = &lt;SPAN&gt;new&lt;/SPAN&gt; MyServiceClient();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   8:&lt;/SPAN&gt;         client.GetDataCompleted += OnGetDataCompleted;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   9:&lt;/SPAN&gt;         client.SaveDataCompleted += OnSaveDataCompleted;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  10:&lt;/SPAN&gt;     }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  11:&lt;/SPAN&gt;     &lt;SPAN&gt;void&lt;/SPAN&gt; OnGetDataCompleted(&lt;SPAN&gt;object&lt;/SPAN&gt; sender, GetDataCompletedEventArgs e)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  12:&lt;/SPAN&gt;     {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  13:&lt;/SPAN&gt;         CallSynchronization&amp;lt;GetDataCompletedEventArgs&amp;gt; sycnContext = (CallSynchronization&amp;lt;GetDataCompletedEventArgs&amp;gt;)e.UserState;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  14:&lt;/SPAN&gt;         sycnContext.Completed(e);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  15:&lt;/SPAN&gt;     }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  16:&lt;/SPAN&gt;     &lt;SPAN&gt;void&lt;/SPAN&gt; OnSaveDataCompleted(&lt;SPAN&gt;object&lt;/SPAN&gt; sender, SaveDataCompletedEventArgs e)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  17:&lt;/SPAN&gt;     {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  18:&lt;/SPAN&gt;         CallSynchronization&amp;lt;GetDataCompletedEventArgs&amp;gt; sycnContext = (CallSynchronization&amp;lt;GetDataCompletedEventArgs&amp;gt;)e.UserState;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  19:&lt;/SPAN&gt;         sycnContext.Completed(e);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  20:&lt;/SPAN&gt;     }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  21:&lt;/SPAN&gt;     &lt;SPAN&gt;public&lt;/SPAN&gt; &lt;SPAN&gt;string&lt;/SPAN&gt; GetData(&lt;SPAN&gt;int&lt;/SPAN&gt; &lt;SPAN&gt;value&lt;/SPAN&gt;)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  22:&lt;/SPAN&gt;     {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  23:&lt;/SPAN&gt;         CallSynchronization&amp;lt;GetDataCompletedEventArgs&amp;gt; syncContext = &lt;SPAN&gt;new&lt;/SPAN&gt; CallSynchronization&amp;lt;GetDataCompletedEventArgs&amp;gt;();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  24:&lt;/SPAN&gt;         client.GetDataAsync(&lt;SPAN&gt;value&lt;/SPAN&gt;, syncContext);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  25:&lt;/SPAN&gt;         syncContext.Wait();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  26:&lt;/SPAN&gt;         &lt;SPAN&gt;if&lt;/SPAN&gt; (sycnContext.Result.Error != &lt;SPAN&gt;null&lt;/SPAN&gt;)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  27:&lt;/SPAN&gt;             &lt;SPAN&gt;throw&lt;/SPAN&gt; sycnContext.Result.Error;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  28:&lt;/SPAN&gt;         &lt;SPAN&gt;else&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  29:&lt;/SPAN&gt;             &lt;SPAN&gt;return&lt;/SPAN&gt; sycnContext.Result.Result; &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  30:&lt;/SPAN&gt;     }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  31:&lt;/SPAN&gt;     &lt;SPAN&gt;public&lt;/SPAN&gt; &lt;SPAN&gt;void&lt;/SPAN&gt; SaveData(&lt;SPAN&gt;int&lt;/SPAN&gt; &lt;SPAN&gt;value&lt;/SPAN&gt;, &lt;SPAN&gt;string&lt;/SPAN&gt; data)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  32:&lt;/SPAN&gt;     {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  33:&lt;/SPAN&gt;         CallSynchronization&amp;lt;SaveDataCompletedEventArgs &amp;gt; syncContext = &lt;SPAN&gt;new&lt;/SPAN&gt; CallSynchronization&amp;lt;SaveDataCompletedEventArgs &amp;gt;();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  34:&lt;/SPAN&gt;         client.SaveDataAsync(&lt;SPAN&gt;value&lt;/SPAN&gt;, data, syncContext);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  35:&lt;/SPAN&gt;         syncContext.Wait();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  36:&lt;/SPAN&gt;         &lt;SPAN&gt;if&lt;/SPAN&gt; (sycnContext.Result.Error != &lt;SPAN&gt;null&lt;/SPAN&gt;)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  37:&lt;/SPAN&gt;             &lt;SPAN&gt;throw&lt;/SPAN&gt; sycnContext.Result.Error;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  38:&lt;/SPAN&gt;         &lt;SPAN&gt;else&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  39:&lt;/SPAN&gt;             &lt;SPAN&gt;return&lt;/SPAN&gt; sycnContext.Result.Result; &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  40:&lt;/SPAN&gt;     }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  41:&lt;/SPAN&gt; }&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;So the call to the sync service will call the async method, setting a ManualResetEvent on the sync Object that will be set back when completed. &lt;BR&gt;With these two simple classes we're now able to call sync methods on wcf services, but we will notice that even if logically correct, the Wait call on the ResetEvent will block the Main UI Thread and from a "wait" state it will pass to a "unreversible Coma state". &lt;BR&gt;The problem as stated, is due to MainDispatcher, Dispatcher is a FrameworkElement property that returns an object used to "resyncing" asynchornous operation in main Silverlight Thread.&lt;/P&gt;
&lt;H4&gt;The Home-Made "MessageLoop"&lt;/H4&gt;
&lt;P&gt;&lt;BR&gt;So we wrote down a Class that "simulate" a MessageLoop, a Stack of statement called synchronously. First of all let's model a Simple "atomic execution block": &lt;BR&gt;&lt;/P&gt;
&lt;DIV&gt;
&lt;DIV&gt;&lt;PRE&gt;&lt;SPAN&gt;   1:&lt;/SPAN&gt; &lt;SPAN&gt;public&lt;/SPAN&gt; &lt;SPAN&gt;class&lt;/SPAN&gt; ExecutorOperation&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   2:&lt;/SPAN&gt;     {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   3:&lt;/SPAN&gt;         &lt;SPAN&gt;// Fields&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   4:&lt;/SPAN&gt;         &lt;SPAN&gt;private&lt;/SPAN&gt; &lt;SPAN&gt;object&lt;/SPAN&gt;[] _args;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   5:&lt;/SPAN&gt;         &lt;SPAN&gt;private&lt;/SPAN&gt; Delegate _operation;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   6:&lt;/SPAN&gt;         &lt;SPAN&gt;private&lt;/SPAN&gt; Action _action;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   7:&lt;/SPAN&gt;         &lt;SPAN&gt;// Methods&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   8:&lt;/SPAN&gt;         &lt;SPAN&gt;internal&lt;/SPAN&gt; ExecutorOperation(Delegate operation, &lt;SPAN&gt;object&lt;/SPAN&gt;[] args)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   9:&lt;/SPAN&gt;         {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  10:&lt;/SPAN&gt;             &lt;SPAN&gt;this&lt;/SPAN&gt;._operation=operation;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  11:&lt;/SPAN&gt;             &lt;SPAN&gt;this&lt;/SPAN&gt;._args=args;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  12:&lt;/SPAN&gt;         }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  13:&lt;/SPAN&gt;         &lt;SPAN&gt;internal&lt;/SPAN&gt; ExecutorOperation(Action action)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  14:&lt;/SPAN&gt;         {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  15:&lt;/SPAN&gt;             &lt;SPAN&gt;this&lt;/SPAN&gt;._action=action;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  16:&lt;/SPAN&gt;             &lt;SPAN&gt;this&lt;/SPAN&gt;._args=&lt;SPAN&gt;null&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  17:&lt;/SPAN&gt;         }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  18:&lt;/SPAN&gt;         &lt;SPAN&gt;internal&lt;/SPAN&gt; &lt;SPAN&gt;void&lt;/SPAN&gt; Invoke()&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  19:&lt;/SPAN&gt;         {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  20:&lt;/SPAN&gt;             &lt;SPAN&gt;if&lt;/SPAN&gt; (_operation!=&lt;SPAN&gt;null&lt;/SPAN&gt;)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  21:&lt;/SPAN&gt;                 &lt;SPAN&gt;this&lt;/SPAN&gt;._operation.DynamicInvoke(&lt;SPAN&gt;this&lt;/SPAN&gt;._args);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  22:&lt;/SPAN&gt;             &lt;SPAN&gt;else&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  23:&lt;/SPAN&gt;                 &lt;SPAN&gt;this&lt;/SPAN&gt;._action.DynamicInvoke(_args);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  24:&lt;/SPAN&gt;         }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  25:&lt;/SPAN&gt;         &lt;SPAN&gt;internal&lt;/SPAN&gt; &lt;SPAN&gt;string&lt;/SPAN&gt; Name&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  26:&lt;/SPAN&gt;         {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  27:&lt;/SPAN&gt;             get&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  28:&lt;/SPAN&gt;             {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  29:&lt;/SPAN&gt;                 &lt;SPAN&gt;if&lt;/SPAN&gt; (_action!=&lt;SPAN&gt;null&lt;/SPAN&gt;)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  30:&lt;/SPAN&gt;                     &lt;SPAN&gt;return&lt;/SPAN&gt; _action.Method.Name;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  31:&lt;/SPAN&gt;                 &lt;SPAN&gt;else&lt;/SPAN&gt; &lt;SPAN&gt;if&lt;/SPAN&gt; (_operation!=&lt;SPAN&gt;null&lt;/SPAN&gt;)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  32:&lt;/SPAN&gt;                     &lt;SPAN&gt;return&lt;/SPAN&gt; _operation.Method.Name;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  33:&lt;/SPAN&gt;                 &lt;SPAN&gt;else&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  34:&lt;/SPAN&gt;                     &lt;SPAN&gt;return&lt;/SPAN&gt; &lt;SPAN&gt;"(Unknown)"&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  35:&lt;/SPAN&gt;             }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  36:&lt;/SPAN&gt;         }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  37:&lt;/SPAN&gt;         &lt;SPAN&gt;internal&lt;/SPAN&gt; &lt;SPAN&gt;bool&lt;/SPAN&gt; IsEndBlock&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  38:&lt;/SPAN&gt;         {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  39:&lt;/SPAN&gt;             get&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  40:&lt;/SPAN&gt;             {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  41:&lt;/SPAN&gt;                 &lt;SPAN&gt;if&lt;/SPAN&gt; (_action!=&lt;SPAN&gt;null&lt;/SPAN&gt;&amp;amp;&amp;amp;_action.Method.DeclaringType==&lt;SPAN&gt;typeof&lt;/SPAN&gt;(Executor)&amp;amp;&amp;amp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  42:&lt;/SPAN&gt;                     _action.Method.Name==&lt;SPAN&gt;"NotifyEndBlock"&lt;/SPAN&gt;)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  43:&lt;/SPAN&gt;                     &lt;SPAN&gt;return&lt;/SPAN&gt; &lt;SPAN&gt;true&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  44:&lt;/SPAN&gt;                 &lt;SPAN&gt;else&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  45:&lt;/SPAN&gt;                     &lt;SPAN&gt;return&lt;/SPAN&gt; &lt;SPAN&gt;false&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  46:&lt;/SPAN&gt;             }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  47:&lt;/SPAN&gt;         }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  48:&lt;/SPAN&gt;     }&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;A simple class that wraps a single operation (invoked with a Delegate or with an action) and with a special property "IsEndBlock" that we will use to instruct the MessageLoop in order to close the queue and to start the execution of every ExecutorOperation instance inside the queue. &lt;BR&gt;It's time to design and implement the Executor class, the main class of entire process. &lt;BR&gt;Well, a first stub is this: &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;DIV&gt;
&lt;DIV&gt;&lt;PRE&gt;&lt;SPAN&gt;   1:&lt;/SPAN&gt; &lt;SPAN&gt;public&lt;/SPAN&gt; &lt;SPAN&gt;class&lt;/SPAN&gt; Executor&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   2:&lt;/SPAN&gt;     {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   3:&lt;/SPAN&gt;         &lt;SPAN&gt;static&lt;/SPAN&gt; Queue&amp;lt;ExecutorOperation&amp;gt; executionQueue=&lt;SPAN&gt;new&lt;/SPAN&gt; Queue&amp;lt;ExecutorOperation&amp;gt;();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   4:&lt;/SPAN&gt;         &lt;SPAN&gt;static&lt;/SPAN&gt; Thread worker;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   5:&lt;/SPAN&gt;         &lt;SPAN&gt;static&lt;/SPAN&gt; ManualResetEvent doLoop;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   6:&lt;/SPAN&gt;         &lt;SPAN&gt;static&lt;/SPAN&gt; AutoResetEvent stoploop;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   7:&lt;/SPAN&gt;         &lt;SPAN&gt;public&lt;/SPAN&gt; &lt;SPAN&gt;static&lt;/SPAN&gt; &lt;SPAN&gt;bool&lt;/SPAN&gt; isInBeginEndBlock=&lt;SPAN&gt;false&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   8:&lt;/SPAN&gt;         &lt;SPAN&gt;public&lt;/SPAN&gt; &lt;SPAN&gt;static&lt;/SPAN&gt; &lt;SPAN&gt;event&lt;/SPAN&gt; EventHandler&amp;lt;BeginBlockEventArgs&amp;gt; BeginExecutionBlock;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   9:&lt;/SPAN&gt;         &lt;SPAN&gt;public&lt;/SPAN&gt; &lt;SPAN&gt;static&lt;/SPAN&gt; &lt;SPAN&gt;event&lt;/SPAN&gt; EventHandler EndExecutionBlock;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  10:&lt;/SPAN&gt;         &lt;SPAN&gt;public&lt;/SPAN&gt; &lt;SPAN&gt;static&lt;/SPAN&gt; &lt;SPAN&gt;event&lt;/SPAN&gt; EventHandler&amp;lt;FailedEventArgs&amp;gt; FailedExecutionBlock;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  11:&lt;/SPAN&gt;         &lt;SPAN&gt;public&lt;/SPAN&gt; &lt;SPAN&gt;static&lt;/SPAN&gt; &lt;SPAN&gt;event&lt;/SPAN&gt; EventHandler&amp;lt;PromptEventArgs&amp;gt; OnPrompt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  12:&lt;/SPAN&gt;         &lt;SPAN&gt;static&lt;/SPAN&gt; PromptResult result;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  13:&lt;/SPAN&gt;         &lt;SPAN&gt;delegate&lt;/SPAN&gt; &lt;SPAN&gt;void&lt;/SPAN&gt; AskForPromptDelegate(&lt;SPAN&gt;string&lt;/SPAN&gt; title, &lt;SPAN&gt;string&lt;/SPAN&gt; message, &lt;SPAN&gt;bool&lt;/SPAN&gt; inputBox, PromptButton button, PromptIcon icon);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  14:&lt;/SPAN&gt;         ...&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  15:&lt;/SPAN&gt;         &lt;SPAN&gt;static&lt;/SPAN&gt; Executor()&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  16:&lt;/SPAN&gt;         {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  17:&lt;/SPAN&gt;             stoploop=&lt;SPAN&gt;new&lt;/SPAN&gt; AutoResetEvent(&lt;SPAN&gt;false&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  18:&lt;/SPAN&gt;             doLoop=&lt;SPAN&gt;new&lt;/SPAN&gt; ManualResetEvent(&lt;SPAN&gt;false&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  19:&lt;/SPAN&gt;             worker=&lt;SPAN&gt;new&lt;/SPAN&gt; Thread(&lt;SPAN&gt;new&lt;/SPAN&gt; ThreadStart(ExecutionLoop));&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  20:&lt;/SPAN&gt;             worker.Start();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  21:&lt;/SPAN&gt;         }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  22:&lt;/SPAN&gt;     }&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;we got a Queue (our messages that have to be dispatched and executed) a Thread, some signals, some delegates and EventHandlers. A static constructor assure us that every needed component is initialized and start our personal implementation of the Message Loop Queue. &lt;BR&gt;In order to give the possibility to our classes to Instruct the message loop we have to tell him when we're starting to enqueuing and when we've finished with the enqueuing, so in our class we will use something like: &lt;BR&gt;&lt;/P&gt;
&lt;DIV&gt;
&lt;DIV&gt;&lt;PRE&gt;&lt;SPAN&gt;   1:&lt;/SPAN&gt; Executor.BeginBlock();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   2:&lt;/SPAN&gt; Executor.Invoke(... our action);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   3:&lt;/SPAN&gt; Executor.EndBlock();&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;BR&gt;and let's see what Begin and End Block methods contains in our Executor class: &lt;BR&gt;&lt;/P&gt;
&lt;DIV&gt;
&lt;DIV&gt;&lt;PRE&gt;&lt;SPAN&gt;   1:&lt;/SPAN&gt; &lt;SPAN&gt;/// &amp;lt;summary&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   2:&lt;/SPAN&gt;         &lt;SPAN&gt;/// The first delegate that the executor needs in order to process the queue&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   3:&lt;/SPAN&gt;         &lt;SPAN&gt;/// &amp;lt;/summary&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   4:&lt;/SPAN&gt;         &lt;SPAN&gt;public&lt;/SPAN&gt; &lt;SPAN&gt;static&lt;/SPAN&gt; &lt;SPAN&gt;void&lt;/SPAN&gt; BeginBlock()&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   5:&lt;/SPAN&gt;         {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   6:&lt;/SPAN&gt;             BeginBlock(&lt;SPAN&gt;null&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   7:&lt;/SPAN&gt;         }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   8:&lt;/SPAN&gt;         &lt;SPAN&gt;public&lt;/SPAN&gt; &lt;SPAN&gt;static&lt;/SPAN&gt; &lt;SPAN&gt;void&lt;/SPAN&gt; BeginBlock(&lt;SPAN&gt;string&lt;/SPAN&gt; message)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   9:&lt;/SPAN&gt;         {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  10:&lt;/SPAN&gt;             &lt;SPAN&gt;if&lt;/SPAN&gt; (isInBeginEndBlock)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  11:&lt;/SPAN&gt;                 &lt;SPAN&gt;return&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  12:&lt;/SPAN&gt;             isInBeginEndBlock=&lt;SPAN&gt;true&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  13:&lt;/SPAN&gt;             Invoke(&lt;SPAN&gt;new&lt;/SPAN&gt; Action&amp;lt;&lt;SPAN&gt;string&lt;/SPAN&gt;&amp;gt;(NotifyBeginBlock), message);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  14:&lt;/SPAN&gt;         }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  15:&lt;/SPAN&gt;         &lt;SPAN&gt;/// &amp;lt;summary&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  16:&lt;/SPAN&gt;         &lt;SPAN&gt;///  Notify the listeners that a BeginBlock have been signaled&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  17:&lt;/SPAN&gt;         &lt;SPAN&gt;/// &amp;lt;/summary&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  18:&lt;/SPAN&gt;         &lt;SPAN&gt;private&lt;/SPAN&gt; &lt;SPAN&gt;static&lt;/SPAN&gt; &lt;SPAN&gt;void&lt;/SPAN&gt; NotifyBeginBlock(&lt;SPAN&gt;string&lt;/SPAN&gt; msg)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  19:&lt;/SPAN&gt;         {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  20:&lt;/SPAN&gt;             &lt;SPAN&gt;if&lt;/SPAN&gt; (BeginExecutionBlock!=&lt;SPAN&gt;null&lt;/SPAN&gt;)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  21:&lt;/SPAN&gt;                 MainDispatcher.Current.BeginInvoke(BeginExecutionBlock, &lt;SPAN&gt;null&lt;/SPAN&gt;, &lt;SPAN&gt;new&lt;/SPAN&gt; BeginBlockEventArgs(msg));&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  22:&lt;/SPAN&gt;         }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  23:&lt;/SPAN&gt;         &lt;SPAN&gt;/// &amp;lt;summary&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  24:&lt;/SPAN&gt;         &lt;SPAN&gt;/// End Block is the starter delegate, once setted this delegate the Executor starts with the dequeuing of operations&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  25:&lt;/SPAN&gt;         &lt;SPAN&gt;/// &amp;lt;/summary&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  26:&lt;/SPAN&gt;         &lt;SPAN&gt;public&lt;/SPAN&gt; &lt;SPAN&gt;static&lt;/SPAN&gt; &lt;SPAN&gt;void&lt;/SPAN&gt; EndBlock()&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  27:&lt;/SPAN&gt;         {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  28:&lt;/SPAN&gt;             &lt;SPAN&gt;if&lt;/SPAN&gt; (!isInBeginEndBlock)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  29:&lt;/SPAN&gt;                 &lt;SPAN&gt;return&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  30:&lt;/SPAN&gt;             isInBeginEndBlock=&lt;SPAN&gt;false&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  31:&lt;/SPAN&gt;             Invoke(NotifyEndBlock);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  32:&lt;/SPAN&gt;             doLoop.Set(); &lt;SPAN&gt;// start dequeue block&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  33:&lt;/SPAN&gt;         }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  34:&lt;/SPAN&gt;         &lt;SPAN&gt;/// &amp;lt;summary&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  35:&lt;/SPAN&gt;         &lt;SPAN&gt;/// Notidy the queue that an EndBlockStatement have been signaled into executor&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  36:&lt;/SPAN&gt;         &lt;SPAN&gt;/// &amp;lt;/summary&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  37:&lt;/SPAN&gt;         &lt;SPAN&gt;private&lt;/SPAN&gt; &lt;SPAN&gt;static&lt;/SPAN&gt; &lt;SPAN&gt;void&lt;/SPAN&gt; NotifyEndBlock()&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  38:&lt;/SPAN&gt;         {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  39:&lt;/SPAN&gt;             &lt;SPAN&gt;if&lt;/SPAN&gt; (EndExecutionBlock!=&lt;SPAN&gt;null&lt;/SPAN&gt;)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  40:&lt;/SPAN&gt;                 MainDispatcher.Current.BeginInvoke(EndExecutionBlock, &lt;SPAN&gt;null&lt;/SPAN&gt;, &lt;SPAN&gt;null&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  41:&lt;/SPAN&gt;         }&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;For notifying purposes we wrote down two events in order to notify every listeners that Executor have been "somehow" started ... and we will notify back when Executor finished his work. Those events are really useful for usability matters, we remember that isn't possible to set MainDispatcher in a "wait state" so we have to simulate something that exclude every possible interaction between User an User Interface (a modal panel with a "please wait" text should work). &lt;BR&gt;So we have methods to start the enqueuing and notify the Executor that we've done with enqueuing, telling him to start, between those statements we put our method invocation list (often only one method that wraps every statement we need) that run in Synchronous mode. The method used in the executor class is Invoke: &lt;BR&gt;&lt;/P&gt;
&lt;DIV&gt;
&lt;DIV&gt;&lt;PRE&gt;&lt;SPAN&gt;   1:&lt;/SPAN&gt; &lt;SPAN&gt;public&lt;/SPAN&gt; &lt;SPAN&gt;static&lt;/SPAN&gt; ExecutorOperation Invoke(Action a)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   2:&lt;/SPAN&gt;        {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   3:&lt;/SPAN&gt;            &lt;SPAN&gt;lock&lt;/SPAN&gt; (executionQueue)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   4:&lt;/SPAN&gt;            {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   5:&lt;/SPAN&gt;                ExecutorOperation operation=&lt;SPAN&gt;new&lt;/SPAN&gt; ExecutorOperation(a);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   6:&lt;/SPAN&gt;                executionQueue.Enqueue(operation);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   7:&lt;/SPAN&gt;                &lt;SPAN&gt;if&lt;/SPAN&gt; (!isInBeginEndBlock)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   8:&lt;/SPAN&gt;                    doLoop.Set();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   9:&lt;/SPAN&gt;                &lt;SPAN&gt;return&lt;/SPAN&gt; operation;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  10:&lt;/SPAN&gt;            }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  11:&lt;/SPAN&gt;        }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  12:&lt;/SPAN&gt;        &lt;SPAN&gt;public&lt;/SPAN&gt; &lt;SPAN&gt;static&lt;/SPAN&gt; ExecutorOperation Invoke(Delegate d, &lt;SPAN&gt;params&lt;/SPAN&gt; &lt;SPAN&gt;object&lt;/SPAN&gt;[] args)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  13:&lt;/SPAN&gt;        {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  14:&lt;/SPAN&gt;            &lt;SPAN&gt;lock&lt;/SPAN&gt; (executionQueue)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  15:&lt;/SPAN&gt;            {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  16:&lt;/SPAN&gt;                ExecutorOperation operation=&lt;SPAN&gt;new&lt;/SPAN&gt; ExecutorOperation(d, args);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  17:&lt;/SPAN&gt;                executionQueue.Enqueue(operation);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  18:&lt;/SPAN&gt;                &lt;SPAN&gt;if&lt;/SPAN&gt; (!isInBeginEndBlock)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  19:&lt;/SPAN&gt;                    doLoop.Set();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  20:&lt;/SPAN&gt;                &lt;SPAN&gt;return&lt;/SPAN&gt; operation;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  21:&lt;/SPAN&gt;            }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  22:&lt;/SPAN&gt;        }&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;Let's have a look to the main logic of our class, a simple method that, with particular care to waitsignals and locks, start to dequeuing our operations and process them. &lt;BR&gt;&lt;/P&gt;
&lt;DIV&gt;
&lt;DIV&gt;&lt;PRE&gt;&lt;SPAN&gt;   1:&lt;/SPAN&gt; &lt;SPAN&gt;/// &amp;lt;summary&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   2:&lt;/SPAN&gt; &lt;SPAN&gt;/// Main logic, dequeue operation when notified from a EndBlock statement and process operations sync&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   3:&lt;/SPAN&gt; &lt;SPAN&gt;/// &amp;lt;/summary&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   4:&lt;/SPAN&gt; &lt;SPAN&gt;private&lt;/SPAN&gt; &lt;SPAN&gt;static&lt;/SPAN&gt; &lt;SPAN&gt;void&lt;/SPAN&gt; ExecutionLoop()&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   5:&lt;/SPAN&gt; {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   6:&lt;/SPAN&gt;     WaitHandle[] events=&lt;SPAN&gt;new&lt;/SPAN&gt; WaitHandle[] { stoploop, doLoop };&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   7:&lt;/SPAN&gt;     &lt;SPAN&gt;while&lt;/SPAN&gt; (&lt;SPAN&gt;true&lt;/SPAN&gt;)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   8:&lt;/SPAN&gt;     {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   9:&lt;/SPAN&gt;         &lt;SPAN&gt;int&lt;/SPAN&gt; eventId=WaitHandle.WaitAny(events);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  10:&lt;/SPAN&gt;         &lt;SPAN&gt;if&lt;/SPAN&gt; (eventId==0) &lt;SPAN&gt;// stopped&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  11:&lt;/SPAN&gt;             &lt;SPAN&gt;break&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  12:&lt;/SPAN&gt;         &lt;SPAN&gt;else&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  13:&lt;/SPAN&gt;         {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  14:&lt;/SPAN&gt;             &lt;SPAN&gt;lock&lt;/SPAN&gt; (executionQueue)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  15:&lt;/SPAN&gt;             {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  16:&lt;/SPAN&gt;                 &lt;SPAN&gt;while&lt;/SPAN&gt; (executionQueue.Count&amp;gt;0)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  17:&lt;/SPAN&gt;                 {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  18:&lt;/SPAN&gt;                     ExecutorOperation operation=executionQueue.Dequeue();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  19:&lt;/SPAN&gt;                     &lt;SPAN&gt;try&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  20:&lt;/SPAN&gt;                     {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  21:&lt;/SPAN&gt;                         Debug.WriteLine(&lt;SPAN&gt;"Executor Invoke: {0}"&lt;/SPAN&gt;, operation.Name);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  22:&lt;/SPAN&gt;                         operation.Invoke();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  23:&lt;/SPAN&gt;                     }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  24:&lt;/SPAN&gt;                     &lt;SPAN&gt;catch&lt;/SPAN&gt; (Exception ex)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  25:&lt;/SPAN&gt;                     {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  26:&lt;/SPAN&gt;                         &lt;SPAN&gt;if&lt;/SPAN&gt; (isInBeginEndBlock)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  27:&lt;/SPAN&gt;                         {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  28:&lt;/SPAN&gt;                             &lt;SPAN&gt;// dequeue until end is reached&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  29:&lt;/SPAN&gt;                             &lt;SPAN&gt;while&lt;/SPAN&gt; (&lt;SPAN&gt;true&lt;/SPAN&gt;)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  30:&lt;/SPAN&gt;                             {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  31:&lt;/SPAN&gt;                                 ExecutorOperation nullOperation=executionQueue.Dequeue();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  32:&lt;/SPAN&gt;                                 &lt;SPAN&gt;if&lt;/SPAN&gt; (nullOperation.IsEndBlock)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  33:&lt;/SPAN&gt;                                 {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  34:&lt;/SPAN&gt;                                     MainDispatcher.Current.BeginInvoke(&lt;SPAN&gt;new&lt;/SPAN&gt; Action&amp;lt;Exception, ExecutorOperation&amp;gt;(NotifyFailed), ex, operation);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  35:&lt;/SPAN&gt;                                     &lt;SPAN&gt;break&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  36:&lt;/SPAN&gt;                                 }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  37:&lt;/SPAN&gt;                             }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  38:&lt;/SPAN&gt;                         }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  39:&lt;/SPAN&gt;                         &lt;SPAN&gt;else&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  40:&lt;/SPAN&gt;                             MainDispatcher.Current.BeginInvoke(&lt;SPAN&gt;new&lt;/SPAN&gt; Action&amp;lt;Exception, ExecutorOperation&amp;gt;(NotifyFailed), ex, operation);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  41:&lt;/SPAN&gt;                     }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  42:&lt;/SPAN&gt;                 }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  43:&lt;/SPAN&gt;                 doLoop.Reset();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  44:&lt;/SPAN&gt;             }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  45:&lt;/SPAN&gt;         }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  46:&lt;/SPAN&gt;     }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  47:&lt;/SPAN&gt; }&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;In order to let this up and running you have to create a simple class that returns in every moment the Dispatcher in order to resync with Silverlight Main Thread, every call that involves modifies to User Interface objects have to be called within MainDispatcher Method. &lt;BR&gt;The Simplest way to do it is to set it in the Application_Startup method of our app: &lt;BR&gt;&lt;/P&gt;
&lt;DIV&gt;
&lt;DIV&gt;&lt;PRE&gt;&lt;SPAN&gt;   1:&lt;/SPAN&gt; &lt;SPAN&gt;public&lt;/SPAN&gt; &lt;SPAN&gt;class&lt;/SPAN&gt; App : Application &lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   2:&lt;/SPAN&gt; {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   3:&lt;/SPAN&gt;     &lt;SPAN&gt;private&lt;/SPAN&gt; &lt;SPAN&gt;void&lt;/SPAN&gt; Application_Startup(&lt;SPAN&gt;object&lt;/SPAN&gt; sender, StartupEventArgs e)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   4:&lt;/SPAN&gt;     {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   5:&lt;/SPAN&gt;         mainDispatcher = &lt;SPAN&gt;this&lt;/SPAN&gt;.RootVisual.Dispatcher;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   6:&lt;/SPAN&gt;     }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   7:&lt;/SPAN&gt;     System.Windows.Threading.Dispatcher mainDispatcher;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   8:&lt;/SPAN&gt;     &lt;SPAN&gt;public&lt;/SPAN&gt; System.Windows.Threading.Dispatcher MainDispatcher&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   9:&lt;/SPAN&gt;     {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  10:&lt;/SPAN&gt;         get&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  11:&lt;/SPAN&gt;         {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  12:&lt;/SPAN&gt;             &lt;SPAN&gt;return&lt;/SPAN&gt; mainDispatcher;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  13:&lt;/SPAN&gt;         }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  14:&lt;/SPAN&gt;     }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  15:&lt;/SPAN&gt; }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  16:&lt;/SPAN&gt; [DebuggerStepThrough]&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  17:&lt;/SPAN&gt; &lt;SPAN&gt;public&lt;/SPAN&gt; &lt;SPAN&gt;static&lt;/SPAN&gt; &lt;SPAN&gt;class&lt;/SPAN&gt; MainDispatcher&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  18:&lt;/SPAN&gt; {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  19:&lt;/SPAN&gt;     &lt;SPAN&gt;public&lt;/SPAN&gt; &lt;SPAN&gt;static&lt;/SPAN&gt; System.Windows.Threading.Dispatcher Current&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  20:&lt;/SPAN&gt;     {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  21:&lt;/SPAN&gt;         get { &lt;SPAN&gt;return&lt;/SPAN&gt; ((App)Application.Current).MainDispatcher; }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  22:&lt;/SPAN&gt;     }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  23:&lt;/SPAN&gt; }&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;H4&gt;Let's try it with silverlight&lt;/H4&gt;
&lt;P&gt;&lt;BR&gt;Let's recall what we've tried to do before executor implementation: &lt;BR&gt;&lt;/P&gt;
&lt;DIV&gt;
&lt;DIV&gt;&lt;PRE&gt;&lt;SPAN&gt;   1:&lt;/SPAN&gt; &lt;SPAN&gt;protected&lt;/SPAN&gt; &lt;SPAN&gt;void&lt;/SPAN&gt; btn_clic(&lt;SPAN&gt;object&lt;/SPAN&gt; sender, RoutedEventArgs e)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   2:&lt;/SPAN&gt; {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   3:&lt;/SPAN&gt;     ServiceApplication client = &lt;SPAN&gt;new&lt;/SPAN&gt; ServiceApplication();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   4:&lt;/SPAN&gt;     &lt;SPAN&gt;string&lt;/SPAN&gt; result = client.DbLookUp(data);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   5:&lt;/SPAN&gt;     InputBoxCanvas icv = &lt;SPAN&gt;new&lt;/SPAN&gt; InputBoxCanvas();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   6:&lt;/SPAN&gt;     &lt;SPAN&gt;string&lt;/SPAN&gt; userInput = icv.ShowModal();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   7:&lt;/SPAN&gt;     client.SaveData(data, userInput);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   8:&lt;/SPAN&gt; }&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;BR&gt;and let's rewrite with our Executor implementation in mind, the odd is that we have to Wrap the method inside another that uses Executor blocks, but no more cascading completed event handler, let's imagine a Silverlight button with a btn_click handler that have to manage the statements we can see in this example, let's write it down: &lt;BR&gt;&lt;/P&gt;
&lt;DIV&gt;
&lt;DIV&gt;&lt;PRE&gt;&lt;SPAN&gt;   1:&lt;/SPAN&gt; &lt;SPAN&gt;protected&lt;/SPAN&gt; &lt;SPAN&gt;void&lt;/SPAN&gt; btn_clic(&lt;SPAN&gt;object&lt;/SPAN&gt; sender, RoutedEventArgs e)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   2:&lt;/SPAN&gt; {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   3:&lt;/SPAN&gt;     Executor.BeginBlock();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   4:&lt;/SPAN&gt;     Executor.Invoke(dostuff);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   5:&lt;/SPAN&gt;     Executor.EndBlock();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   6:&lt;/SPAN&gt; }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   7:&lt;/SPAN&gt; &lt;SPAN&gt;protected&lt;/SPAN&gt; &lt;SPAN&gt;void&lt;/SPAN&gt; doStuff()&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   8:&lt;/SPAN&gt; {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;   9:&lt;/SPAN&gt;     MyServiceClientSync client = &lt;SPAN&gt;new&lt;/SPAN&gt; MyServiceClientSync();&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  10:&lt;/SPAN&gt;     &lt;SPAN&gt;string&lt;/SPAN&gt; result = client.GetData(&lt;SPAN&gt;this&lt;/SPAN&gt;.txtInput1.Text);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  11:&lt;/SPAN&gt;     &lt;SPAN&gt;if&lt;/SPAN&gt; (result == &lt;SPAN&gt;"OK"&lt;/SPAN&gt;)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  12:&lt;/SPAN&gt;          client.SaveData(&lt;SPAN&gt;this&lt;/SPAN&gt;.txtInput1.Text, &lt;SPAN&gt;this&lt;/SPAN&gt;.DataToSave.Text);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN&gt;  13:&lt;/SPAN&gt; }&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;BR&gt;It's clear, it's not as in (for instance) winform, but we're able to call a sequence of statements in synchronous way even if those statements will go to get data from database or open some prompt message and wait for user input.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H4&gt;Conclusions: &lt;/H4&gt;
&lt;P&gt;Our implementation of Executor is extendible, we hooked in it some handlers in order to manage common operations like Showing modal "Wait panels", asking for user prompt, notifying exceptions. It's open to every idea in order to get this component working better.&lt;/P&gt;
&lt;P&gt;We're also testing it in order to understand if there is any silent bug behind it (memory leaks or unexpected exceptions).&lt;/P&gt;
&lt;P&gt;We're sure this is not the best way to work, perhaps Async is better, but we're also sure that developers, even if often bad developers, have to fail in order to understand, and if fail differs form something that brings to understanding well, they will remain bad developers.&lt;/P&gt;
&lt;P&gt;We're sure that silverlight should not be used only for video straming.&lt;/P&gt;
&lt;P&gt;We simulate a synchronous way to work with, we don't implemented a synchronous call to wcf services.&lt;/P&gt;
&lt;P&gt;Feedback are really appreciated (and needed for improvements) !&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;Reference:&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;&lt;A href="http://www.rickgaribay.net/archive/2008/03/07/silverlight-2.0-service-integration-three-steps-forward-two-steps-back.aspx" target=_blank&gt;http://www.rickgaribay.net/archive/2008/03/07/silverlight-2.0-service-integration-three-steps-forward-two-steps-back.aspx&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://neverindoubtnet.blogspot.com/2008/07/big-silverlight-troubles-no-synchronous.html" target=_blank&gt;http://neverindoubtnet.blogspot.com/2008/07/big-silverlight-troubles-no-synchronous.html&lt;/A&gt;&lt;/P&gt;&lt;img src="http://blog.avanadeadvisor.com/aggbug.aspx?PostID=11652" width="1" height="1"&gt;</content><author><name>grava</name><uri>http://blog.avanadeadvisor.com/members/grava.aspx</uri></author></entry><entry><title>Mi presento ...</title><link rel="alternate" type="text/html" href="http://blog.avanadeadvisor.com/blogs/grava/archive/2008/07/15/11459.aspx" /><id>http://blog.avanadeadvisor.com/blogs/grava/archive/2008/07/15/11459.aspx</id><published>2008-07-15T08:17:59Z</published><updated>2008-07-15T08:17:59Z</updated><content type="html">&lt;p&gt;Ecco il mio primo post ... mi presento. Mi chiamo Gianluca Gravina, lavoro per Avanade (dove altrimenti ?) a Milano. Lavoro oramai dal 2002 in ambiente Ms / .NET.&lt;/p&gt;  &lt;p&gt;In cosa consiste il mio lavoro ???&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Architettura delle soluzioni .NET (Analisi e sviluppo)&lt;/li&gt;    &lt;li&gt;Desing Patterns&lt;/li&gt;    &lt;li&gt;ORM (NHibernate)&lt;/li&gt;    &lt;li&gt;Active Record&lt;/li&gt;    &lt;li&gt;Design for Testability&lt;/li&gt;    &lt;li&gt;TDD&lt;/li&gt;    &lt;li&gt;Metodologie Agili (SCRUM)&lt;/li&gt;    &lt;li&gt;Monorail (MVC)&lt;/li&gt;    &lt;li&gt;Asp.NET Mvc&lt;/li&gt;    &lt;li&gt;...&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;e molto altro ...&lt;/p&gt;  &lt;p&gt;Cosa troverete su questo blog ?&lt;/p&gt;  &lt;p&gt;Se il tempo me ne dar&amp;#224; la possibilit&amp;#224; cerchero di postare qualche info / tip riguardanti le tecnologie che via via mi trover&amp;#242; ad usare ... (in questo momento potreste trovare qualche post su Silverlight 2v2).&lt;/p&gt;  &lt;p&gt;Dove potete trovarmi nella blogosfera ?&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.ugidotnet.org/thinkingingrava"&gt;http://blogs.ugidotnet.org/thinkingingrava&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.facebook.com/home.php#/profile.php?id=576722563" target="_blank"&gt;Facebook&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.linkedin.com/in/gianlucagravina" target="_blank"&gt;Linkedin&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;A presto !&lt;/p&gt;  &lt;p&gt;Gianluca&lt;/p&gt;&lt;img src="http://blog.avanadeadvisor.com/aggbug.aspx?PostID=11459" width="1" height="1"&gt;</content><author><name>grava</name><uri>http://blog.avanadeadvisor.com/members/grava.aspx</uri></author></entry></feed>