<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.devleap.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Articoli DevLeap</title><subtitle type="html">Articoli DevLeap</subtitle><id>http://blogs.devleap.com/articolidevleap/atom.aspx</id><link rel="alternate" type="text/html" href="http://blogs.devleap.com/articolidevleap/default.aspx" /><link rel="self" type="application/atom+xml" href="http://blogs.devleap.com/articolidevleap/atom.aspx" /><generator uri="http://communityserver.org" version="3.0.20611.960">Community Server</generator><updated>2006-01-12T18.06.00Z</updated><entry><title>Visual Studio 2010: primo contatto (parte 4)</title><link rel="alternate" type="text/html" href="http://blogs.devleap.com/articolidevleap/archive/2008/12/03/visual-studio-2010-primo-contatto-parte-4.aspx" /><id>http://blogs.devleap.com/articolidevleap/archive/2008/12/03/visual-studio-2010-primo-contatto-parte-4.aspx</id><published>2008-12-03T14.12.00Z</published><updated>2008-12-03T14.12.00Z</updated><content type="html">&lt;p&gt;Autore: &lt;a href="http://blogs.devleap.com/rob" target="_blank"&gt;Roberto Brunetti&lt;/a&gt; - &lt;a href="http://www.devleap.com/" target="_blank"&gt;DevLeap&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Per questo articolo facciamo qualcosa di più concreto come abbiamo fatto nel precedente: Ho preso il nostro ormai famoso progetto EstatesManagement (una parte dei 75 progetti, ho preso solo il BIZ+DAL+UI via Web) presentato alla &lt;a&gt;DevCon 2005&lt;/a&gt;, &lt;a href="http://devcon2007.devleap.com/"&gt;2007&lt;/a&gt; e &lt;a href="http://devcon2008.devleap.com/"&gt;2008&lt;/a&gt; nelle sue varie evoluzioni e che vedrà altre evoluzioni verso .NET 4.0 e VSTS 2010 nella nostra prossima conferenza: &lt;a class="" href="http://devcon2009.devleap.com/"&gt;DevCon 2009&lt;/a&gt;. [Update: Link]&lt;/p&gt;
&lt;p&gt;Una delle idee dietro la nuova versione di VSTS 2010 è fornire strumenti per analizzare e comprendere il codice esistente. Partiamo proprio dall’analisi dell’applicazione EstatesManagement.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Understanding Existing Assets (Bottom-up Approach)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Nota: ho portato i vari progetti alla 4.0 durante la conversione (e lo fa per tutti: anche dll).&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Architecture Explorer&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Si parte dalla definizione delle classi: Class View&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image002.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image002" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image002_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cliccando sulla classe&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image0021.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image002[1]" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image0021_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Si espandono i “contenuti”&lt;/p&gt;
&lt;p&gt;Fra un “tab” e l’altro si può vedere&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image004.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image004" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image004_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Che consente di filtrare per Classi – Comunicazione Outbound, inbound, cose non implementate&lt;/p&gt;
&lt;p&gt;Ed eseeguire comandi come Generate WorkItem, Opem, Inser Into ActiveDiagram&lt;/p&gt;
&lt;p&gt;Dalle classi invece il filtro contiene Field, Method, altri classi, inherits from, called by, container by. Cose pubbliche, chi sono i derivati di questa classe etc&lt;/p&gt;
&lt;p&gt;Scendendo sui metodi si vedono le chiamate&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Grafici standard&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Generate New Graph a partire dalla selezione corrente &lt;br /&gt;si aggiunge poi quello che voglio analizzare (con la doppia freccia verde)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image006.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image006" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image006_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Aggiungendo Salesman e BaseEntity&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image008.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image008" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image008_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Si può arrivare a livello di field&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image010.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image010" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image010_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Doppio click su un pezzo si va nel codice reale evidenziato rispetto al resto (Es su SalesmanDescritpion)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image012.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image012" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image012_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Dipendenze fra Assemblies o Namespace o Classi&lt;/p&gt;
&lt;p&gt;Es relazione fra Namespace&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image014.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image014" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image014_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Le linee sono più fini o più spesse a seconda del livello di dipendenza: semplicemente le linee molto fini hanno 1 sola chiamata (quindi dipendenza), mentre le linee più spesse hanno molte chiamate.&lt;/p&gt;
&lt;p&gt;Si può espandere ogni nodo per ottenere le classi contenuti&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image016.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image016" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image016_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Esempio di dipendenze fra classi (e all’interno i vari membri)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image018.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image018" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image018_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Se si seleziona una classe appaiono i link dettagliati verso gli altri namespace (o classi se il namespace di arrivo è aperto) e con il “cazzillo” si può andare da una parte all’altra del link:&lt;/p&gt;
&lt;p&gt;Ogni diagramma è in XML con estensione .dgml. Si possono salvare per analisi future&lt;/p&gt;
&lt;p&gt;Ci sono varie viste: ad esempio a Stack, TreeView, Nested Stack, &lt;/p&gt;
&lt;p&gt;&lt;b&gt;Sequence diagram&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Sempre continuando con la parte di “Understanding existing code” è possibile generare il Sequence Diagram UML a partire da qualunque metodo esistente e tenere sincronizzato il tutto.&lt;/p&gt;
&lt;p&gt;Da qualunque metodo si può fare tasto destro:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image020.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image020" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image020_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Questo il diagramma del nostro metodo List filtrando per Current Project (quindi si vedono le chiamate fatte solo alle “cose” di questo progetto&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image022.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image022" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image022_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Filtrando per entire solution il nostro metodo che chiama la nostra libreria SqlHelper (simile a DAAB), crea una classe SalesmanList (che sta nel progetto .Entities) e nel ciclo costruisce la classe Salesmna (anch’essa nel progetto .Entities) per ogni venditore del DB, si ottiene questo. N.B. ho fatto due screenshot perchè oggi la mia macchina virtuale non ne vuole sapere del copia/incolla fuori verso l’host.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image024.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image024" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image024_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image026.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image026" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image026_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Il diagramma creato prende l’estensione .sequence e viene inserito nel progetto da cui è stato “reserverd engineered”&lt;/p&gt;
&lt;p&gt;Su ogni elemento si può fare tasto destro per vedere il tutto nell’architecture explorer, per scendere nel codice o creare (nel caso di aggiunta di “pezzi”) classi o interfarfacce.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Layer Diagram&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Sta in un progetto di tipo Modeling (dove ci stanno i diagrammi UML)&lt;/p&gt;
&lt;p&gt;Ad esempio nel nostro caso anche il Biz Layer effettivo ha chiamate verso il progetto Entitiy che sta sotto Entitities. Ecco gli errori&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image028.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image028" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte4_D5FC/clip_image028_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I Layer possono essere anche composti da SottoLayer per dividere ulteriormente i layer: vedere i due articoli precedenti a partire da &lt;a href="http://blogs.devleap.com/articolidevleap/archive/2008/10/26/visual-studio-team-system-2010-primo-contatto-parte-2.aspx"&gt;http://blogs.devleap.com/articolidevleap/archive/2008/10/26/visual-studio-team-system-2010-primo-contatto-parte-2.aspx&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Links agli articoli precedenti:&lt;/p&gt;
&lt;p&gt;Intro Parte 1 : &lt;a href="http://blogs.devleap.com/articolidevleap/archive/2008/10/17/visual-studio-team-system-2010-primo-contatto.aspx"&gt;http://blogs.devleap.com/articolidevleap/archive/2008/10/17/visual-studio-team-system-2010-primo-contatto.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Intro Parte 2: &lt;a href="http://blogs.devleap.com/articolidevleap/archive/2008/10/26/visual-studio-team-system-2010-primo-contatto-parte-2.aspx"&gt;http://blogs.devleap.com/articolidevleap/archive/2008/10/26/visual-studio-team-system-2010-primo-contatto-parte-2.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Parte 3 Testing &amp;amp; Dubugging: &lt;a title="http://blogs.devleap.com/articolidevleap/archive/2008/11/30/visual-studio-2010-primo-contatto-parte-3.aspx" href="http://blogs.devleap.com/articolidevleap/archive/2008/11/30/visual-studio-2010-primo-contatto-parte-3.aspx"&gt;http://blogs.devleap.com/articolidevleap/archive/2008/11/30/visual-studio-2010-primo-contatto-parte-3.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.devleap.com/articolidevleap/archive/2008/10/26/visual-studio-team-system-2010-primo-contatto-parte-2.aspx"&gt;&lt;/a&gt;&lt;/p&gt;Link a .NET 4.0 
&lt;p&gt;Workflow Foundation 4.0: &lt;a href="http://blogs.devleap.com/articolidevleap/archive/2008/11/17/workflow-foundation-4-0-introduzione-alle-ctp-ottobre-2008.aspx"&gt;http://blogs.devleap.com/articolidevleap/archive/2008/11/17/workflow-foundation-4-0-introduzione-alle-ctp-ottobre-2008.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Dublin: &lt;a href="http://blogs.devleap.com/articolidevleap/archive/2008/11/14/dublin-windows-application-server.aspx"&gt;http://blogs.devleap.com/articolidevleap/archive/2008/11/14/dublin-windows-application-server.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.devleap.com/aggbug.aspx?PostID=18717" width="1" height="1"&gt;</content><author><name>rob</name><uri>http://blogs.devleap.com/members/rob.aspx</uri></author><category term="VSTS" scheme="http://blogs.devleap.com/articolidevleap/archive/tags/VSTS/default.aspx" /><category term=".NET 4.0" scheme="http://blogs.devleap.com/articolidevleap/archive/tags/.NET+4.0/default.aspx" /></entry><entry><title>Visual Studio 2010: primo contatto (parte 3)</title><link rel="alternate" type="text/html" href="http://blogs.devleap.com/articolidevleap/archive/2008/11/30/visual-studio-2010-primo-contatto-parte-3.aspx" /><id>http://blogs.devleap.com/articolidevleap/archive/2008/11/30/visual-studio-2010-primo-contatto-parte-3.aspx</id><published>2008-11-30T13.57.00Z</published><updated>2008-11-30T13.57.00Z</updated><content type="html">&lt;p&gt;Autore: &lt;a href="http://blogs.devleap.com/rob" target="_blank"&gt;Roberto Brunetti&lt;/a&gt; - &lt;a href="http://www.devleap.com/" target="_blank"&gt;DevLeap&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;In questa puntata ci concentriamo su Testing &amp;amp; Dubugging.&lt;/p&gt;
&lt;p&gt;In VSTS2010 è stato aggiunto il supporto per la validazione della user interface. Si parte da un progetto di test con Add New Guided UI Test.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image002.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image002" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image002_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Si sceglie “Launch recorder to generate code”&lt;/p&gt;
&lt;p&gt;L’idea è registrare cosa stiamo facendo e generare il codice per testare user interface WinForm e ASP.NET (e forse WPF già nella release 2010). Per Silverlight probabilmente occorrera aspettare ancora un pò.&lt;/p&gt;
&lt;p&gt;Ad esempio eseguendo qualche click su questo form si ottiene questa registrazione&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image004.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image004" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image004_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Poi si genera il codice tramite il pulsante evidenziato “Generate Code” (stare molto attenti: si siamo in debug posizionare prima il cursore nel metodo di test prima di generare il codice); meglio lanciare prima l’applicazione e poi registrare, al posto di fare F5 diretto da Visual Studio: almeno in questa prima CTP di ottobre 2008.&lt;/p&gt;
&lt;p&gt;Per fare la validazione della UI si prende il UI Control Validator (tasto destro sul metodo o sul recorder a registrazione ferma premere “Add Validation”)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image006.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image006" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image006_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Per attivare il controllo si prende il “cazzillo” bianco in alto a destra del panel UI Control Finder e si fa un drag sul controllo da testare: con le freccie ci si può spostare sui controlli da testare.&lt;/p&gt;
&lt;p&gt;Per ogni controllo si fa Add e al termine (done) si vedono le proprietà di ogni controllo e si impostano i valori di test.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image008.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image008" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image008_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In questo caso dichiaro che il checkbox deve essere disabilitato. Come si nota si possono controllare più o meno tutte le proprietà (colori, visibilità, focus, etc)&lt;/p&gt;
&lt;p&gt;Al lanio del test creato viene fatta girare di nuovo l’applicazione (compleso l’F5 da VS se è stato registrato o l’apertura del browser, oppure l’applicazione deve essere aperta):&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image010.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image010" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image010_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Sono andato anche a fare un giro sul sistema operativo per capire come si muove il registratore, e direi che ci segue molto bene.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image012.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image012" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image012_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Si vede la registrazione del Task Manager.&lt;/p&gt;
&lt;p&gt;Per far partire un test si può fare tasto destro sul test e Run oppure, come sempre dalla finestra Test View.&lt;/p&gt;
&lt;p&gt;Gli Unit Test aiutano, ma in VSTS 2010 si va oltre con Impact Analysis e Historical Debugger, affrontati in modo introduttivo nella prossima sezione.&lt;/p&gt;
&lt;p&gt;Vediamo prima qualche dettaglio sul codice generato dallo strumento “Coded UI Test”.&lt;/p&gt;
&lt;p&gt;Oltre al file xxx.cs, visto in precedenza, per il coded test viene creato &lt;/p&gt;
&lt;p&gt;1) un file UIMap.uitest&lt;/p&gt;
&lt;p&gt;2) un file RecordedMethods.cs&lt;/p&gt;
&lt;p&gt;3) UserControl.cs&lt;/p&gt;
&lt;p&gt;UIMap.uitest è in xml e contiene per ogni elemento (ad esempio la lstElementi)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image014.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="430" alt="clip_image014" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image014_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Il file .cs allegato contiene le classi che consentono a questo framework di recuperare i controlli, definire i criteri di ricerca dei controlli andando per derivazione di alcune classi base: ad esempio LstElementWindow del file xml precedente è un classe definità così:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image016.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="430" alt="clip_image016" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image016_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Si deriva da WinWindow restituendo nel Get di LstElementList l’elemento di tipo WinList (ricordiamoci che si tratta di una finestra Windows Form).&lt;/p&gt;
&lt;p&gt;Il codice dello unit test usa metodi del file RecordedMethods.cs che rappresentano i metodi da lanciare per eseguire il test: questi metodo sono stati creati durante la registrazione:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image018.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="430" alt="clip_image018" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image018_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Questi metodi rappresentano appunto lo unit test da eseguire. Ecco il codice:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image020.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="430" alt="clip_image020" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image020_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Come si nota viene creata la struttura per cercare, nel nostro esempio, il pulsante denominato Controlla (dove “Controlla” è il Text del pulsante) e su questo viene eseguito un click nel punto 39,13.&lt;/p&gt;
&lt;p&gt;Il file UserControls.cs (che immagino verrà poi inserito nelle librerie Microsoft e non all’interno di ogni progetto come adesso) contiene la definizione dei vari controlli utilizzati (WinButton, WinCheckBox) e ne definisce le proprietà visibili (e quindi controllabili dalla mascherina di validazione del Coded UI Test).&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Software Diagnostics and QoS&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Bug Prevention: trovarli il prima possibile è la nostra missione.&lt;/p&gt;
&lt;p&gt;Oggi in VSTS 2008: Code Analysis per trovare qualche defect strutturale o codice scritto male, ancora prima di lanciare il codice. Il Profiler inoltre ci da una mano fin dalle prime fasi. Poi ci sono gli Unit Test che possono intercettare i bug, poi in produzione si può fare tracing. VSTS 2010 prosegue su questa linea aggiungendo due strumenti interni e uno strumento esterno.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;VSTS2010 prima feature: Impact Analysis&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image022.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image022" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image022_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Quando cambio del codice vedo quali test dovrebbero essere lanciati perchè la modifica impatta il codice testato da questo test. Nella finestra selezionare il team project e la relativa build.&lt;/p&gt;
&lt;p&gt;Serve una Build perchè il mapping fra test e metodi sta dentro TFS insieme ai risultati dei test. Il file di mapping server-side viene caricato in VS per controllare questo mapping.&lt;/p&gt;
&lt;p&gt;Selezionata la Build e modificando qualche riga di codice, al momento del salvataggio viene controllato l’impatto:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image024.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image024" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image024_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In questo caso la modifica che ho fatto (che ha toccato il metodo Somma) non impatta su nessun test. Questo strumento consente di verificare anche il famoso problema “One Code Line Change”: non preoccupiamoci, sto modificando solo una riga di codice, non posso fare casino J. In questo modo sappiamo a colpo d’occhio quali test dover rilanciare. Esiste poi (almeno l’ho trovata nel prodotto) una check in policy che consente di bloccare un check-in se il codice modificato ha impattato su alcuni test che non sono stati lanciati:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image026.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image026" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image026_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Inoltre la finestra “Test Impact Analysis” indica anche tutti i metodi modificati dall’ultimo check-out: è quindi comodissimo anche per capire cosa ha fatto; sembra una cosa stupida, ma durante lo sviuppo di una parte di codice spesso (almeno a me accade) saltiamo da un metodo all’altro, e spesso siamo interrotti da una mail (la prima regola dello sviluppatore è: tenere posta, messenger, skype, telefonino...SPENTI, ma spesso questa non è la situazione classica in molti uffici). Ritornando sul codice occorre capire dove eravamo, cosa avevamo fatto: la finestrina aiuta in questo !&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Secondo strumento: Hystorical Debugger&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Serve per tornare al punto esatto per capire cosa abbiamo fatto durante il debugging.&lt;/p&gt;
&lt;p&gt;Si può vedere cosa è successo prima del nostro breakpoint o dove abbiamo riscontrato un errore: in pratica si può risalire la call stack per capire cosa è successo precedentemente (cosa è accaduto nel metodo che ha chiamato questo metodo).&lt;/p&gt;
&lt;p&gt;Facendo un esempio stupido, ma spero calzante: al click di un pulsante eseguo questo codice:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image028.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image028" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image028_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Sperando che si legga nel post (ingrandire l’immagine cliccandoci sopra), si nota che chiamo la funzione Somma, dal click del mio pulsante, una prima volta con due numeri random (potrebbero essere presi ovviamente da un record nel DB o da un file di testo). Al risultato delle mia funzione devo aggiungere un altro valore (sempre random nel mio semplice caso, ma ancora una volta può arrivare da dove vogliamo).&lt;/p&gt;
&lt;p&gt;Al primo breakpoint si vede che a e b sono 1402002823. Ecco lo screenshot, notare la finestra “Locals”&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image030.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image030" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image030_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Facendo F5 chiaramente mi rifermo al breakpoint di Somma e i due valori saranno diversi, come si nota sempre dalla finestra “Locals”:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image032.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image032" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image032_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Se mi accorgo di un problema sul valore che mi aspetto, ad oggi in VSTS 2008 è difficile capire quali valori erano stati usati nella prima somma (magari i dati nel DB sono cambiati, o il file di testo ha numeri diversi perchè nel processo è stato aggiornato: controllare quindi i dati di origine diventa complicato se non imposssibile) è ed un casino risalire alla natura del problema e capire perchè sono finito in questa situazione.&lt;/p&gt;
&lt;p&gt;L’hystorical debugger consente di risalire lo stack per verificare cosa è successo: nella finestra a destra si vede infatti che il Thread 5936 ha eseguito il metodo Main che ha chiamato il form su cui si è eseguito il metodo cmd_HistoricalDebugger (è il nome del mio pulsante) il quale adesso sta eseguendo il metodo Somma. Fin quì niente di particolare: è una call stack.&lt;/p&gt;
&lt;p&gt;Se però faccio doppio click sul metodo cmd_HystoricalDebugger vedo che ho eseguito due volte il metodo somma:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image034.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image034" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image034_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;E facendo doppio click sul primo ritorno indietro nella storia e posso analizzare nuovamente il contenuto delle variabili sia nella classiche mascherine Auto/Local/Immediate/Watch o nella finestra in basso a destra:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image036.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image036" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image036_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Come si nota si vedono i valori 1402002823 per a e b del metodo somma che erano i valori passati alla prima chiamata a Somma.&lt;/p&gt;
&lt;p&gt;Pensato al caso in cui stiamo debuggando il Business Layer su dati arrivati dal DataAccess Layer: ci accorgiamo nell’esecuzione del codice che qualche dato non è come ci aspettavamo; possiamo tornare su cosa ha fatto il DataAccess Layer per capire come mai ci sono arrivati dati strani, possiamo capire se i metodi che abbiamo richiamato hanno fatto il loro lavoro.&lt;/p&gt;
&lt;p&gt;Per abilitare o configurare il tutto dal Tools/Options, nella sezione debug.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image038.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image038" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image038_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Terzo Strumento: Test Activity Center “Camano”&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Non occorre VS, è una interfaccia stand-alone con accesso diretto a TFS, che presenta i vari test case per ogni progetto.&lt;/p&gt;
&lt;p&gt;L’idea è risolvere il problema “It works on my machine” e il Test RePro ovvero il problema di riprodurre un bug che durante la fase di test si è verificato, ma che non “esce fuori” sulla macchina di sviluppo. Migliora anche la collaborazione fra Tester e Developer: sono presenti vari collector (configurabili) per prendere informazioni sul sistema che viene testato (Action Log, Event Log, System Information, Debug Information, Video Recorder anche !). Quindi quando si lancia un test case vengono registrate tutte queste informazioni.&lt;/p&gt;
&lt;p&gt;Il test case è composto da varie attività da eseguire manualmente per fare le verifiche. Ogni attività ha poi il flag per indicare se è andato a buon fine o no.&lt;/p&gt;
&lt;p&gt;Questa una idea rispetto al form che abbiamo già visto all’inizio di questo articolo. Lavoriamo senza collegare Requirements o Build per semplicità e per rimanere sul punto senza divagare:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image040.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image040" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image040_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Una volta creato il Test Case, dal Test Suite Manager si organizzano i test case in Test Suite. Ad esempio, ho creato una Test Suite denominata Prove UI Manuali che comprende il test case “Visualizzazione Listbox” creato in precedenza:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image042.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image042" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image042_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Per organizzare meglio il lavoro si organizzano i piani di itest in Test Plan: ecco la creazione del Test Plan “Prove su User Interface Manuali” che comprende la test suite appena creata. Per ogni Plan si indicano i classici Test Run, a cui però in VSTS2010 si associa un nome, una suite e una configurazione.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image044.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image044" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image044_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;E’ tutto, possiamo tornare sulla home page del menù testing per lanciare il nostro test e raccogliere i dati. Notare nello screenshot seguente la gerarchia appena creata: un Test Run contiene varie Test Suite che a loro volta contengono i test case:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image046.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image046" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image046_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Quindi da “Prove su User Interface Manuali” che rappresenta il nostro piano di esecuzione dei test, si sceglie la suite e al suo interno il test case.&lt;/p&gt;
&lt;p&gt;Prima di fare Run assicuriamoci che la nostra Test Settings contenga le informazioni che desideriamo registrare. Ho abilitato quasi tutto J&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image048.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image048" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image048_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A questo punto si lancia il test case e con Automation, si registrano tutte le fasi del manual test. Alla fine del processo si può fare il replay delle cose fatte a mano durante la registrazione. Ci sono molti hook nel CLR dove questi strumenti si agganciano quindi non occorre prevedere degli hook nel nostro codice per fare le prime analisi.&lt;/p&gt;
&lt;p&gt;Sto ripercorrendo i primi due step che risultano ok e quindi ho marcato come “Pass”:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image050.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image050" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image050_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Adesso clicco sul pulsante Controlla e marco lo step come Pass, ma visto che ripremendo il pulsante non accade quello che ho segnato come controllo sullo step da effettuare marco l’ultimo step come fallito:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image052.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image052" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image052_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Da questo punto posso poi rivedere la registrazione, ripercorrere gli step e controllare eventuali commenti inseriti (ci sono molte opzioni, come ad esempio l’inserimento di checkpoint, ma in questo articolo introduttivo direi di saltarli per non complicarci la vita).&lt;/p&gt;
&lt;p&gt;I risultato vengono pubblicati e sono disponibili i report su quanto abbiamo fatto. Nel nostro semplice caso abbiamo un solo test case, in una sola suite, con una sola configurazione, con un solo Test Plan, quindi il risultato è alquanto banale:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image054.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image054" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image054_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Facendo doppio click sul test fallito si apre la maschera di dettaglio:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image056.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image056" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image056_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;E ovviamente cliccando sul video (in basso TC280.wmw) si ripercorre cosa abbiamo fatto.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image058.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image058" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image058_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Nel log (TC280.txt) invece sono presenti queste voci:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image060.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image060" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image060_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Se troviamo un bug, alla creazione del bug su TFS vengono aggiunte tutte le informazioni raccolte. &lt;/p&gt;
&lt;p&gt;Ovviamente molte di queste operazioni si possono fare da Visual Studio, o meglio dal Team Explorer, da cui poi si possono rivedere i dati. Entrambi gli strumenti lavorano sullo stesso store:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image062.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="429" alt="clip_image062" src="http://devlab.devleap.it/robertob/immagini/posts/VisualStudio2010primocontattoparte3_D4CD/clip_image062_thumb.jpg" width="606" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Direi che anche per questo terzo articolo della serie Visual Studio 2010 ci fermiamo.&lt;/p&gt;
&lt;p&gt;Alla prossima.&lt;/p&gt;
&lt;p&gt;Links a precedenti articoli:&lt;/p&gt;
&lt;p&gt;Intro Parte 1 : &lt;a href="http://blogs.devleap.com/articolidevleap/archive/2008/10/17/visual-studio-team-system-2010-primo-contatto.aspx"&gt;http://blogs.devleap.com/articolidevleap/archive/2008/10/17/visual-studio-team-system-2010-primo-contatto.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Intro Parte 2: &lt;a href="http://blogs.devleap.com/articolidevleap/archive/2008/10/26/visual-studio-team-system-2010-primo-contatto-parte-2.aspx"&gt;http://blogs.devleap.com/articolidevleap/archive/2008/10/26/visual-studio-team-system-2010-primo-contatto-parte-2.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Link a .NET 4.0&lt;/p&gt;
&lt;p&gt;Workflow Foundation 4.0: &lt;a title="http://blogs.devleap.com/articolidevleap/archive/2008/11/17/workflow-foundation-4-0-introduzione-alle-ctp-ottobre-2008.aspx" href="http://blogs.devleap.com/articolidevleap/archive/2008/11/17/workflow-foundation-4-0-introduzione-alle-ctp-ottobre-2008.aspx"&gt;http://blogs.devleap.com/articolidevleap/archive/2008/11/17/workflow-foundation-4-0-introduzione-alle-ctp-ottobre-2008.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Dublin: &lt;a title="http://blogs.devleap.com/articolidevleap/archive/2008/11/14/dublin-windows-application-server.aspx" href="http://blogs.devleap.com/articolidevleap/archive/2008/11/14/dublin-windows-application-server.aspx"&gt;http://blogs.devleap.com/articolidevleap/archive/2008/11/14/dublin-windows-application-server.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.devleap.com/aggbug.aspx?PostID=18716" width="1" height="1"&gt;</content><author><name>rob</name><uri>http://blogs.devleap.com/members/rob.aspx</uri></author></entry><entry><title>Workflow Foundation 4.0: Introduzione alle CTP Ottobre 2008</title><link rel="alternate" type="text/html" href="http://blogs.devleap.com/articolidevleap/archive/2008/11/17/workflow-foundation-4-0-introduzione-alle-ctp-ottobre-2008.aspx" /><id>http://blogs.devleap.com/articolidevleap/archive/2008/11/17/workflow-foundation-4-0-introduzione-alle-ctp-ottobre-2008.aspx</id><published>2008-11-17T18.42.00Z</published><updated>2008-11-17T18.42.00Z</updated><content type="html">&lt;p&gt;Autore: &lt;a href="http://blogs.devleap.com/rob" target="_blank"&gt;Roberto Brunetti&lt;/a&gt; - &lt;a href="http://www.devleap.com/" target="_blank"&gt;DevLeap&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;La prima novità che salta all’occhio è il nuovo designer, fatto in WPF e sicuramente per adesso non definitivo nella forma e colori.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image002.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="470" alt="clip_image002" src="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image002_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;La toolbox presenta molte activity aggiuntive, alcune delle quali tratteremo in questa breve introduzione.&lt;/p&gt;
&lt;p&gt;Partiamo con la prima novità che riguarda le custom activity: in questo semplice progetto, come si nota, ho creato un progetto separato “CustomActivities” con due semplicissime activity: ReadLine e WriteLine; la prima ha il compito di leggere gli input dell’utente nel prompt dei comandi e la seconda di eseguire una Console.WriteLine.&lt;/p&gt;
&lt;p&gt;Partiamo dalla seconda: per eseguire una WriteLine su Console l’activity ha bisogno del testo da visualizzare; in WF 4.0 è possibile definire i parametri di input e di output delle activity senza la necessità dover creare proprietà pubbliche o dependency property come avviene per la versione.&lt;/p&gt;
&lt;p&gt;Questo il codice dell’activity:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image004.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="470" alt="clip_image004" src="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image004_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;E’ stato definito in parametro di input (InArgument), che, sfruttando i generics dichiara che il tipo di parametro è string. L’altra novità rispetto alla versione 3.0/3.5 è la derivazione della nostra activity da WorkflowElement e non da Activity.&lt;/p&gt;
&lt;p&gt;L’override del metodo Execute sin dalla versione 3.0 consente di indicare il codice da eseguire durante l’esecuzione dell’attività e riceve come sempre l’AEC (Activity Execution Context); per recuperare il valore del parametro di input si esegure this.Text.Get passando sempre il Context. Visto che il tipo di parametro è string non occorrono altre operazioni per estrarre eventuali proprietà di una classe più complessa che potremmo ricevere.&lt;/p&gt;
&lt;p&gt;Stesso ragionamento per il parametro di output dell’activity (anzi del WorkflowElement) ReadLine; ecco il codice:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image006.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="470" alt="clip_image006" src="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image006_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In questo caso si usa il Set su outArguments passando sempre l’AEC ricevuto.&lt;/p&gt;
&lt;p&gt;E’ possibile definire le activity interamente in XAML: ecco un esempio di activity che definisce tre parametri &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image008.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="470" alt="clip_image008" src="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image008_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Costruite le activity (in xaml o in code) siamo quindi pronti per il nostro primo worfklow 4.0 che può utilizzare in sequenza WriteLine e Readline per chiaccherare con l’utente tramite la console.&lt;/p&gt;
&lt;p&gt;Ecco il flusso completo&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image0021.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="470" alt="clip_image002[1]" src="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image0021_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;La prima WriteLine deve scrivere a video un messaggio che l’autore del workflow può impostare liberamente. Nelle proprietà dell’activity (come nella versione 3.x) è possibile indicare il valore del parametro direttamente nel designer:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image010.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="360" alt="clip_image010" src="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image010_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;La successiva ReadLine, come abbiamo visto nel codice, espone un parametro di output denominato outArgument che dovrà essere passato come parametro di input alla successiva WriteLine che semplicemente lo visualizzerà nella console.&lt;/p&gt;
&lt;p&gt;In WF 3.x questo passaggio di informazioni fra una activity e l’altra era prossibile tramite il binding diretto fra la proprietà di una activity e la proprietà dell’altra activity: il meccanismo è sicuramente semplice ma crea un problema di “scope” ovvero: quando muoiono questa variabili esposte dalle activity ? Visto che teoricamente è possibile fare il binding fra activity presenti nell’intero workflow sequenzale, il runtime del workflow è costretto a tenere in vità questa variabili fino a che non termina l’instanza del workflow, cosa che causa anche un tempo di serializzazione/deserializzazione durante la persistenza del workflow.&lt;/p&gt;
&lt;p&gt;In WF 4.0 è possibile creare variabile all’interno di uno scope: ad esempio è possibile definire una variabile a livello di sequence che quindi “nascerà” all’inizio della sequenza e “morirà” alla fine della stessa. Queste variabili sono poi bindable verso i parametri di input e output delle varie activity presenti nello stesso scope, ovvero nella sequence per proseguire con il nostro esempio.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image012.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="470" alt="clip_image012" src="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image012_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;La finestrina si apre dall’apposito pulsante nella toolbar in basso e consente di definire appunto le variabili visibli all’interno dello scope. La finestra mostra anche le variabili disponibili che arrivano da variabili definite nel contenitore dell’activity corrente: ad esempio inserendo una sequnce all’interno del nostro flusso principale (che a sua volta è una sequence) avremmo la visibilità della variabili della sequence padre anche sul figlio. Ecco la figurina esemplificativa:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image014.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="470" alt="clip_image014" src="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image014_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Come si nota le variabili Destinazione (e Prezzo) sono disponibili anche nella sequence figlia e vengono separate come visualizzazione nella parte alta Variable Available.&lt;/p&gt;
&lt;p&gt;Le variabili a livello di scope possono essere bindate ai parametri di input e output della varie activity: nel nostro caso quindi ospitiamo la destinazione del nostro volo nella variabile Destinazione durante la ReadLine e la WriteLine successiva. La Readline avrà il parametro di ouput legato alla Destinazione e la WriteLine avrà il parametro di input legato sempre a Destinazione.&lt;/p&gt;
&lt;p&gt;Ecco la Readline:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image016.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="360" alt="clip_image016" src="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image016_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Per adesso l’editor, in questa primissima CTP di Ottobre 2008, non fornisce nessun aiuto (tipo intellisense e enumeration) delle variabili disponibili.&lt;/p&gt;
&lt;p&gt;La WriteLine nel nostro flusso farà esattamente la stessa cosa...o quasi. E’ possibile legare ad un parametro di input (o anche ad una variabile) una espressione: il binding quindi consente non solo di legare un parametro ad un altro, ma anche di eseguire una espressione durante il binding. Ad esempio la nostra WriteLine può contenere questo:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image018.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="360" alt="clip_image018" src="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image018_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In questo semplice esempio abbiamo lavorato con delle stringhe, ma ovviamente il discorso è valido per altri tipi di dato: questo consente all’autore di workflow di eseguire espressioni (che vengono valutate dal runtime) per assegnare (o anche leggere) valori ai parametri o alle variabili.&lt;/p&gt;
&lt;p&gt;Per avviare un workflow (o meglio una istanza di workflow) nel WF 3.0/3.5 occorre avviare il workflow runtime, configurarlo adeguatamente e poi chiedere al workflow runtime di creare e avviare una istanza. Questo il codice di una applicazione console per rimanere in tema:&lt;/p&gt;
&lt;p&gt;#region Using directives&lt;/p&gt;
&lt;p&gt;using System;&lt;/p&gt;
&lt;p&gt;using System.Collections.Generic;&lt;/p&gt;
&lt;p&gt;using System.Text;&lt;/p&gt;
&lt;p&gt;using System.Threading;&lt;/p&gt;
&lt;p&gt;using System.Workflow.Runtime;&lt;/p&gt;
&lt;p&gt;using System.Workflow.Runtime.Hosting;&lt;/p&gt;
&lt;p&gt;#endregion&lt;/p&gt;
&lt;p&gt;namespace _5_CodeCondition&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;class Program&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;static void Main(string[] args)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;AutoResetEvent waitHandle = new AutoResetEvent(false);&lt;/p&gt;
&lt;p&gt;workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e) &lt;br /&gt;{waitHandle.Set();};&lt;/p&gt;
&lt;p&gt;workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs &lt;br /&gt;e)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;Console.WriteLine(e.Exception.Message);&lt;/p&gt;
&lt;p&gt;waitHandle.Set();&lt;/p&gt;
&lt;p&gt;};&lt;/p&gt;
&lt;p&gt;WorkflowInstance instance = &lt;br /&gt;workflowRuntime.CreateWorkflow(typeof(_5_CodeCondition.Workflow1));&lt;/p&gt;
&lt;p&gt;instance.Start();&lt;/p&gt;
&lt;p&gt;waitHandle.WaitOne();&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Ecco il codice 4.0, direi molto più semplice per avviare la sequnce del nostro esempio.&lt;/p&gt;
&lt;p&gt;namespace TravelSearchApplication&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;using System;&lt;/p&gt;
&lt;p&gt;using System.Linq;&lt;/p&gt;
&lt;p&gt;using System.Threading;&lt;/p&gt;
&lt;p&gt;using System.WorkflowModel;&lt;/p&gt;
&lt;p&gt;using System.WorkflowModel.Activities;&lt;/p&gt;
&lt;p&gt;class Program&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;static void Main(string[] args)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;Sequence s;&lt;/p&gt;
&lt;p&gt;AutoResetEvent syncEvent = new AutoResetEvent(false);&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WorkflowInstance myInstance = WorkflowInstance.Create(new Sequence1());&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;myInstance.Completed += delegate(object sender, WorkflowCompletedEventArgs e) { syncEvent.Set(); };&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;myInstance.Resume();&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;syncEvent.WaitOne();&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Complicando leggermente il nostro esempio supponiamo di voler chiamare un servizio WCF che espone le informazioni sui voli in base alla destinazione scelta. A prescindere da come viene creato il servizio server-side (in WCF 4.0 è possibile definire un servizio interamente in xaml), tramite la ClientOperation possiamo indicare il binding, il contratto e la operation da eseguire:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image020.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="470" alt="clip_image020" src="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image020_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Nel nostro caso usiamo BasicHttpBinding sull’endpoint localhost:8080/service1.xamlx (come accennavo il servizio è scritto interamente in xaml) utilizzando il contratto Contract1 sulla operazione GetData.&lt;/p&gt;
&lt;p&gt;Anche in questo caso è possibile fare binding fra i parametri di ingresso e uscita dell’operation rispetto alla variabili del nostro scope:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image022.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="484" alt="clip_image022" src="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image022_thumb.jpg" width="387" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Il servizio accetta in input il parametro String denominato Destination a cui è verrà legata la nostra ormai famosa variabile Destinazione e risponderà con un valore Double denominato Prezzo che viene legato alla nostra variabile Prezzo (che verrà poi usata per visualizzare il risultato).&lt;/p&gt;
&lt;p&gt;L’ultima activity del nostro workflow non farà altro che passare la variabile Prezzo alla WriteLine con il metodo che ormai conosciamo:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image024.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="321" alt="clip_image024" src="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image024_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Personalmente non mi è chiara una cosa: abbiamo dovuto usare VB.NET per eseguire l’espressione di conversione del Prezzo (Double) in String. Sulla documentazione attuale e alla Professional Developers Conference 2008 di Losa Angeles è stato indicato che le espressioni si scrivono appunto solo in VB.NET. Non ho capito se l’idea sarà questa anche per la versione finale del prodotto o semplicemente per adesso. My Fault.&lt;/p&gt;
&lt;p&gt;Anche se l’articolo è su WF 4.0, vale la pena di dare un occhio a come ho realizzato il servizio server-side: no code ! La descrizione del contratto, delle operation e relativi parametri, nonchè le operazioni da eseguire a fronte di una chiamata sono definite in xaml. Ecco la parte server:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image026.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="470" alt="clip_image026" src="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image026_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;L’activity utilizzata descrivere il contratto è ServiceOperation ed è ospitata nel file service1.xamlx (la x finale indica al motore di esecuzione che si tratta di un servizio attivabile tramite WAS di IIS7).&lt;/p&gt;
&lt;p&gt;Per descrivere il contratto (non è la maschera definitiva) si usa questa mascherina:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image028.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="484" alt="clip_image028" src="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image028_thumb.jpg" width="506" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;E scendendo in Edit sull’operazione GetData si vedono i parametri Destination e Prezzo che sonon stati usati nella client operation che abbiamo descritto prima:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image030.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="484" alt="clip_image030" src="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image030_thumb.jpg" width="479" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;E’ possibile indicare il flusso Two-way o One-way e il supporto alle transazioni, oltre ai criteri ovvi di security.&lt;/p&gt;
&lt;p&gt;Torniamo a WF 4.0: per calcolare il prezzo, il nostro servizio deve eseguire alcune regole in base alla destinazione. Per questo è stato usato (sempre dentro la definizione xamlx del servizio che rappresenta i passi del workflow da eseguire all’arrivo di una richiesta di GetData) un nuovo componente di WF 4.0 denominato Flowchart.&lt;/p&gt;
&lt;p&gt;Espandendo il Flowchart si ottiene questo:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image032.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="470" alt="clip_image032" src="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image032_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Sul rombo con la X si indica la variabile su cui effettuare il test (nel nostro caso Destination) e ogni braccio del flowchart indica il valore che attiva il braccio stesso: nel nostro caso vediamo che sul primo braccio è indicato Brescia nella finestra delle proprietà:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image034.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="470" alt="clip_image034" src="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image034_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Altra novità della versione 4.0 è l’activity di Assign che valorizza la variabile Price con un valore (o una espressione). Nel nostro caso quindi il volo su Brescia costra 1.000, mentre il volo su Firenze costa 500; negli altri casi si scatena una eccezione che poi verrà convertita in un SOAP Fault.&lt;/p&gt;
&lt;p&gt;Una volta calcolato il prezzo base (1000 o 500 nel nostro caso) il flowchart riunisce il flusso per entrare in un RuleSet: chi conosce i RuleSet di Worklfow 3.x si troverà davanti un editor completamente diverso (e molto più intuitivo) che consente di validare una serie di regole (con sequence, chaining, full chaining e reevalutation).&lt;/p&gt;
&lt;p&gt;Il nuovo editor si presenta così, e appunto anche in questa prima CTP è molto più intuitivo dell’attuale:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image036.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="470" alt="clip_image036" src="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image036_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Le regole possono avere nomi descrittivi, il che aiuta molto nell’individuazione delle regole.&lt;/p&gt;
&lt;p&gt;Una volta esplosa (nel senso buono J) una regola ottengo la visualizzazione delle espressioni di valutazione:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image038.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="470" alt="clip_image038" src="http://devlab.devleap.it/robertob/immagini/posts/Workflow.0IntroduzionealleCTPOttobre2008_114BC/clip_image038_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Se DiscountLevel = 1 Then DiscountPoint = 0.95. L’assegnazione si effettua sempre tramite l’activity di assign.&lt;/p&gt;
&lt;p&gt;Per mettere in produzione il nostro servizio che comprende il workflow ci si può affidare alla feature di Dublin di cui trovate un articolo introduttivo sempre nella sezione articolidevleap del sito blogs.devleap.com.&lt;/p&gt;
&lt;p&gt;Ecco l’url completo: &lt;a href="http://blogs.devleap.com/articolidevleap/archive/2008/11/14/dublin-windows-application-server.aspx"&gt;http://blogs.devleap.com/articolidevleap/archive/2008/11/14/dublin-windows-application-server.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Per un primo contatto su Visual Studio 2010 trovate i seguenti due articoli:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.devleap.com/articolidevleap/archive/2008/10/17/visual-studio-team-system-2010-primo-contatto.aspx"&gt;http://blogs.devleap.com/articolidevleap/archive/2008/10/17/visual-studio-team-system-2010-primo-contatto.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.devleap.com/articolidevleap/archive/2008/10/26/visual-studio-team-system-2010-primo-contatto-parte-2.aspx"&gt;http://blogs.devleap.com/articolidevleap/archive/2008/10/26/visual-studio-team-system-2010-primo-contatto-parte-2.aspx&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Roberto Brunetti&lt;/p&gt;&lt;img src="http://blogs.devleap.com/aggbug.aspx?PostID=18705" width="1" height="1"&gt;</content><author><name>rob</name><uri>http://blogs.devleap.com/members/rob.aspx</uri></author><category term=".NET 4 - VS 2010" scheme="http://blogs.devleap.com/articolidevleap/archive/tags/.NET+4+-+VS+2010/default.aspx" /><category term=".NET 4.0" scheme="http://blogs.devleap.com/articolidevleap/archive/tags/.NET+4.0/default.aspx" /></entry><entry><title>Dublin: Windows Application Server</title><link rel="alternate" type="text/html" href="http://blogs.devleap.com/articolidevleap/archive/2008/11/14/dublin-windows-application-server.aspx" /><id>http://blogs.devleap.com/articolidevleap/archive/2008/11/14/dublin-windows-application-server.aspx</id><published>2008-11-14T15.27.00Z</published><updated>2008-11-14T15.27.00Z</updated><content type="html">&lt;p&gt;di &lt;a class="" href="http://blogs.devleap.com/rob" target="_blank"&gt;Roberto Brunetti&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Questo articolo vuole essere una introduzione sulla prima CTP di Dublin ovvero Windows Application Server, almeno per adesso: il nome in codice Dublin fa riferimento anche ad altri meandri della tecnologia. In questa introduzione vediamo all&amp;#39;opera la parte del Windows Application Server.&lt;/p&gt;
&lt;p&gt;E&amp;#39; costruito sopra il .NET Framework 4.0&amp;nbsp; e integra IIS e SQL Server per fornire una piattaforma per la gestione, la configurazione, lo sviluppo e il deploymnet di soluzioni WF/WCF (4.0 appunto).&lt;/p&gt;
&lt;p&gt;Si compone di estensioni per integrare Visual Studio (2010) nel processo di deployment di una soluzione WF/WCF verso l&amp;#39;application server e una serie di strumenti per gestire, localmente o remotamente, la configurazione dell&amp;#39;applicazione ospitata sull&amp;#39;application server. &lt;/p&gt;
&lt;p&gt;Attualmente è necessario creare il proprio ambiente di host, sia esso un servizio windows, un Windows Activated Service (WAS) o una applicazione ASP.NET, a mano, ricorrendo a file di configurazione .config, installazione di componenti, configurazione dei binding rispetto alle porte IIS e così via. Il Windows Application Server consente di gestire tutte queste componenti tramite una interfaccia di amministrazione che consente di esportare e importare applicazioni, vedere le istanze in esecuzione, tracciare i dati di tracking di un workflow, analizzare e terminare le istanze fallite.&lt;/p&gt;
&lt;p&gt;Iniziamo a capire meglio il tutto partendo da uno screenshot (cliccare sulle immagine per visualizzarle a dimensione originale):&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/01_IISExtensionWindowsApplicationServer.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="470" alt="01_IISExtensionWindowsApplicationServer" src="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/01_IISExtensionWindowsApplicationServer_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Siamo sul Default Web Site di IIS Manager (su un Windows Server 2008). Come si nota nella parte in basso delle Features View, l&amp;#39;installazione del Windows Application Server ha aggiunto dei moduli per &lt;/p&gt;
&lt;p&gt;1) Esportazione e importazione di applicazioni: come vedremo più avanti è possibile esportare una applicazione, ad esempio dall&amp;#39;ambiente di test e importarla, completa di configurazione, nell&amp;#39;ambiente di produzione&lt;/p&gt;
&lt;p&gt;2) Database Configuration: consente di gestire le connessioni verso i database di persistenza, tracking e monitoraggio.&lt;/p&gt;
&lt;p&gt;3) Diagnostics: consente di configurare il livello di tracing degli errori e message logging rispetto al tipo di errore nell&amp;#39;applicazione e ai messaggi in ingresso&lt;/p&gt;
&lt;p&gt;4) Persisted Instances: visualizza le istanza di workflow persistite nei vari database configurati&lt;/p&gt;
&lt;p&gt;5) Tracking Configuration e Profile: consentono di gestire profili di tracking per i worflow in esecuzione (come i Tracking Profile di Workflow 3.0) e associarli al database che dovra accogliere queste informazioni.&lt;/p&gt;
&lt;p&gt;Procediamo per gradi, questa la maschera di configurazione dei DB:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/01b_DBConfiguration.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="470" alt="01b_DBConfiguration" src="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/01b_DBConfiguration_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Come si nota, la mia configurazione prevede un database ProcessServerDB come store di default per le istanze persistite di workflow e un database ProductionStore (che in realtà si appoggia sempre allo stesso database fisico) dove appoggiare le istanze dei workflow persistiti. Sempre nello stesso database fisico vengono appoggiati i dati di monitoring (per il tracking delle istanze di workflow) denominato DefaultMonitoringStore. Nel database fisico troveremo quindi le tabelle adibite al monitoring, tabelle con il prefisso defaultStore per tenere le istanze persistite.&lt;/p&gt;
&lt;p&gt;Come è facile intuire i servizi in esecuzione si baseranno sul nome indicato nella colonna Persistence e i dati ad essi associati verranno memorizzati nei (nel caso indicato nell&amp;#39;unico) database fisici configurati.&lt;/p&gt;
&lt;p&gt;Accedendo al modulo Services, si accede alla seguente maschera che consente di visualizzare i servizi installati, di cui vengono riepilogati il nome, il path rispetto alla Virtual directory IIS, il nome del site che ospita la virtual directory, e l&amp;#39;application pool in cui gira il servizio.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/02_Services.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="470" alt="02_Services" src="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/02_Services_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Nel mio caso, ho aperto la maschera dei services, sulla virtual directory ProductionPizzaOrderService e quindi ottengo la lista dei servizi presenti in questa virtual directory.&lt;/p&gt;
&lt;p&gt;Aprendo il maschera dal default web site ottengo ovviamente la visualizzazione di tutti i servizi ospitati sul site di default:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/02b_Services.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="470" alt="02b_Services" src="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/02b_Services_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Su ogni servizio è possibile visualizzare gli endpoint disponibili. Ecco un esempio della maschera che riepiloga i binding di tutti i servizi.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/02c_EndPoint.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="470" alt="02c_EndPoint" src="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/02c_EndPoint_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;E&amp;#39; possibile visualizzare le istanze dei workflow in esecuzione, dei workflow andati in errore, dei workflow bloccati, dei workflow sospesi, dei workflow Ready-to-run: nella versione attuale di workflow foundation è possibile accedere ai valori numerici solo dal performance monitor, che non fornisce però i dettagli rispetto ai counter. Con il Windows Application Server, oltre ai counter riepilogativi che si vedono nella seguente immagine&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/03_PersistedInstanceSummary.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="470" alt="03_PersistedInstanceSummary" src="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/03_PersistedInstanceSummary_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;è possibile cliccare sui vari contatori per capire a cosa si riferiscono i numeri. Ad esempio cliccando su Instances Running (2 sono le istanze riportate anche come suspended) si accede al dettaglio di ogni istanza:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/05_PersitedServiceInstance.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="470" alt="05_PersitedServiceInstance" src="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/05_PersitedServiceInstance_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Come si nota appare il dettaglio che indica che ci sono due istanze del PizzaOrderService, ospitate dal Default Web Site, sulla virtual directory Production... che stanno girando.&lt;/p&gt;
&lt;p&gt;Su ogni istanza è possibile, tramite il tasto destro, sospendere l&amp;#39;instanza, terminarla, abortirla o visualizzare i dati di tracking, ovvero l&amp;#39;elenco dei passi (in base al profilo di tracking scelto) che sono stati eseguiti.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/06_PersitedServiceInstanceTerminate.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="470" alt="06_PersitedServiceInstanceTerminate" src="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/06_PersitedServiceInstanceTerminate_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Ad esempio, se sul servizio PizzaOrderService (nella maschera che abbiamo visto prima riguardante i Services) si sceglie Configure Tracking, è possibile abilitare la configurazione di tracking più appropriata: ogni configurazione comprende il riferimento allo store di monitoring (indicando il nome logico come abbiamo visto nello screenshot relativo) e il profilo di tracking (esiste anche nella versione 3.0 il concetto di Tracking Profile) da utilizzare. Il profilo indica quali attività e quali eventi tracciare su ognuna di esse e può essere completamente personalizzato come vedremo più avanti.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/07_TrackingConfiguration.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="344" alt="07_TrackingConfiguration" src="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/07_TrackingConfiguration_thumb.jpg" width="388" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Una volta impostata la configurazione di tracking su un certo servizio è possibile, dalla mascherina precedente visualizzare i dati di tracking per ogni istanza: tramite il filtro in alto è possibile scegliere lo stato fra Running, Suspended, Blocked, Ready To Run.&lt;/p&gt;
&lt;p&gt;Ecco il risultato:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/08_PersitedServiceInstanceTrackingData.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="470" alt="08_PersitedServiceInstanceTrackingData" src="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/08_PersitedServiceInstanceTrackingData_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Come si può notare per l&amp;#39;instanza selezionata si vedono gli eventi che indicano lo stato (AEC) di ogni activity e il &amp;quot;momento&amp;quot; in cui si sono scatenati.&lt;/p&gt;
&lt;p&gt;Attualmente esiste nell&amp;#39;SDK di Workflow 3.x un editor di Tracking Profile, prodotto efficace ma abbastanza rudimentale. Nella prossima versione il Tracking Profile Editor si presenta così (almeno in questa primissima CTP di ottobre 2008):&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/09_TrackingProfileEditorSample.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="470" alt="09_TrackingProfileEditorSample" src="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/09_TrackingProfileEditorSample_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Il TPE consente di vedere il workflow e indicare quali sono gli eventi da tracciare (la mia freccia rossa indica da dove eseguire questa impostazione) e volendo le variabili (è una novità di workflow 4.0 poter definire variabili a livello di composite activity) da inserire nei dati di tracking.&lt;/p&gt;
&lt;p&gt;Come dicevano all&amp;#39;inizio è possibile esportare e importare una applicazione da un server all&amp;#39;altro portandosi dietro la configurazione.&lt;/p&gt;
&lt;p&gt;Questa la maschera di esportazione:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/10_ApplicationExport.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="470" alt="10_ApplicationExport" src="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/10_ApplicationExport_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;In pratica si sceglie il servizio da esportare e si indica il nome di un file .zip da creare. Il contenuto dello zip è il seguente:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/11_ZipContent.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="278" alt="11_ZipContent" src="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/11_ZipContent_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Il file applicationManifest.xml contiene le informazioni sull&amp;#39;applicazione, sull&amp;#39;application pool (e relativa configurazione) che la ospita, la virtual directory e il path fisico, oltre ad una serie di informazioni sulle modifiche, il tipo di accesso, i protocolli abilitati e la descrizione di tutti i file (dll, proj, etc) che compongono l&amp;#39;applicazione. Ecco il contenuto facilmente intuibile anche se lunghetto :-). Ho evidenziato i punti salienti.&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;Application xmlns:i=&amp;quot;&lt;b&gt;http://www.w3.org/2001/XMLSchema-instance&lt;/b&gt;&amp;quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Id&amp;gt;85c8dc43-1161-4188-8324-de5a831f1431&amp;lt;/Id&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;LpsVersion&amp;gt;3.0.1341.0&amp;lt;/LpsVersion&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;Modules&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;Module&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;ApplicationPool&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;CpuAffinityEnabled&amp;gt;false&amp;lt;/CpuAffinityEnabled&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;CpuAffinityMask&amp;gt;4294967295&amp;lt;/CpuAffinityMask&amp;gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;CpuLimit&amp;gt;0&amp;lt;/CpuLimit&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;CpuLimitAction&amp;gt;NoAction&amp;lt;/CpuLimitAction&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;CpuLimitInterval&amp;gt;PT5M&amp;lt;/CpuLimitInterval&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;FrameworkVersion&amp;gt;v4.0&amp;lt;/FrameworkVersion&amp;gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;IdentityType&amp;gt;SpecificUser&amp;lt;/IdentityType&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;IdleTimeout&amp;gt;PT20M&amp;lt;/IdleTimeout&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;ManagedPipelineMode&amp;gt;Integrated&amp;lt;/ManagedPipelineMode&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;MaxWorkerProcesses&amp;gt;1&amp;lt;/MaxWorkerProcesses&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Name&amp;gt;User Services Application Pool&amp;lt;/Name&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;OverlappedRecycleDisabled&amp;gt;false&amp;lt;/OverlappedRecycleDisabled&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;PingEnabled&amp;gt;true&amp;lt;/PingEnabled&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;PingMaxResponseTime&amp;gt;PT1M30S&amp;lt;/PingMaxResponseTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;PingPeriod&amp;gt;PT30S&amp;lt;/PingPeriod&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;ProcessOrphaningEnabled&amp;gt;false&amp;lt;/ProcessOrphaningEnabled&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;ProcessOrphaningExecutable /&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;ProcessOrphaningExecutableParameters /&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;QueueLength&amp;gt;1000&amp;lt;/QueueLength&amp;gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;RapidFailProtectionEnabled&amp;gt;true&amp;lt;/RapidFailProtectionEnabled&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;RapidFailProtectionFailureInterval&amp;gt;PT5M&amp;lt;/RapidFailProtectionFailureInterval&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;RapidFailProtectionMaxFailures&amp;gt;5&amp;lt;/RapidFailProtectionMaxFailures&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;RapidFailProtectionResponseType&amp;gt;HttpLevel&amp;lt;/RapidFailProtectionResponseType&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;RapidFailProtectionShutdownExecutable /&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;RapidFailProtectionShutdownExecutableParameters /&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;RecyclingEventLogs&amp;gt;Time, Memory, PrivateMemory&amp;lt;/RecyclingEventLogs&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;RecyclingForConfigurationChangesDisabled&amp;gt;false&amp;lt;/RecyclingForConfigurationChangesDisabled&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;RecyclingPrivateMemoryLimit&amp;gt;0&amp;lt;/RecyclingPrivateMemoryLimit&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;RecyclingRegularTimeInterval&amp;gt;P1DT5H&amp;lt;/RecyclingRegularTimeInterval&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;RecyclingRequestLimit&amp;gt;0&amp;lt;/RecyclingRequestLimit&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;RecyclingSpecificTimes xmlns:a=&amp;quot;http://schemas.microsoft.com/2003/10/Serialization/Arrays&amp;quot; /&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;RecyclingVirtualMemoryLimit&amp;gt;0&amp;lt;/RecyclingVirtualMemoryLimit&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;ShutdownTimeLimit&amp;gt;PT1M30S&amp;lt;/ShutdownTimeLimit&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;StartAutomatically&amp;gt;true&amp;lt;/StartAutomatically&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;StartupTimeLimit&amp;gt;PT1M30S&amp;lt;/StartupTimeLimit&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;UserName&amp;gt;Administrator&amp;lt;/UserName&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/ApplicationPool&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Id&amp;gt;6ca9913a-a35a-49a8-8420-2d6d069541be&amp;lt;/Id&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;IisVersion&amp;gt;7.0&amp;lt;/IisVersion&amp;gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;MachineName&amp;gt;ROBDUBLIN&amp;lt;/MachineName&amp;gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Name&amp;gt;/PizzaOrderService&amp;lt;/Name&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Technology&amp;gt;WAS&amp;lt;/Technology&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;TimeStamp&amp;gt;2008-11-04T13:26:38.8691696-08:00&amp;lt;/TimeStamp&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;VirtualApplication&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;AccessPolicy&amp;gt;513&amp;lt;/AccessPolicy&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;AnonymousAccess&amp;gt;true&amp;lt;/AnonymousAccess&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;ApplicationPoolName&amp;gt;User Services Application Pool&amp;lt;/ApplicationPoolName&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;DirectoryBrowsing&amp;gt;true&amp;lt;/DirectoryBrowsing&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;EnabledProtocols&amp;gt;http&amp;lt;/EnabledProtocols&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;LogVisits&amp;gt;true&amp;lt;/LogVisits&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;VirtualDirectories&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;VirtualDirectory&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Attributes&amp;gt;Normal&amp;lt;/Attributes&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;Directories&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;Directory&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Attributes&amp;gt;Normal&amp;lt;/Attributes&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Directories /&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Files /&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;FullPath&amp;gt;C:\HandsOnLabs\Lab6\PizzaOrderingApplication\PizzaOrderService\App_Data&amp;lt;/FullPath&amp;gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Name&amp;gt;App_Data&amp;lt;/Name&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/Directory&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;Directory&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Attributes&amp;gt;Normal&amp;lt;/Attributes&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Directories /&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;Files&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;File&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Attributes&amp;gt;Archive&amp;lt;/Attributes&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;CreationTime&amp;gt;2008-09-23T12:56:08-07:00&amp;lt;/CreationTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;LastAccessTime&amp;gt;2008-09-23T12:56:08-07:00&amp;lt;/LastAccessTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;LastWriteTime&amp;gt;2008-09-23T12:56:08-07:00&amp;lt;/LastWriteTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Name&amp;gt;PizzaOrderingService.dll&amp;lt;/Name&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;PackageKey&amp;gt;PizzaOrderService\bin\PizzaOrderingService.dll&amp;lt;/PackageKey&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/File&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;File&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Attributes&amp;gt;Archive&amp;lt;/Attributes&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;CreationTime&amp;gt;2008-09-23T12:56:08-07:00&amp;lt;/CreationTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;LastAccessTime&amp;gt;2008-09-23T12:56:08-07:00&amp;lt;/LastAccessTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;LastWriteTime&amp;gt;2008-09-23T12:56:08-07:00&amp;lt;/LastWriteTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Name&amp;gt;PizzaOrderingService.pdb&amp;lt;/Name&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;PackageKey&amp;gt;PizzaOrderService\bin\PizzaOrderingService.pdb&amp;lt;/PackageKey&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/File&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/Files&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;FullPath&amp;gt;C:\HandsOnLabs\Lab6\PizzaOrderingApplication\PizzaOrderService\bin&amp;lt;/FullPath&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Name&amp;gt;bin&amp;lt;/Name&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/Directory&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;Directory&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Attributes&amp;gt;Normal&amp;lt;/Attributes&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;Directories&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;Directory&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Attributes&amp;gt;Normal&amp;lt;/Attributes&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;Directories&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;Directory&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Attributes&amp;gt;Normal&amp;lt;/Attributes&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Directories /&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Files /&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;FullPath&amp;gt;C:\HandsOnLabs\Lab6\PizzaOrderingApplication\PizzaOrderService\obj\Debug\TempPE&amp;lt;/FullPath&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Name&amp;gt;TempPE&amp;lt;/Name&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/Directory&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/Directories&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;Files&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;File&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Attributes&amp;gt;Archive&amp;lt;/Attributes&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;CreationTime&amp;gt;2008-09-23T12:56:10-07:00&amp;lt;/CreationTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;LastAccessTime&amp;gt;2008-09-23T12:56:10-07:00&amp;lt;/LastAccessTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;LastWriteTime&amp;gt;2008-09-23T12:56:10-07:00&amp;lt;/LastWriteTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;Name&amp;gt;PizzaOrderingService.dll&amp;lt;/Name&amp;gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;PackageKey&amp;gt;PizzaOrderService\obj\Debug\PizzaOrderingService.dll&amp;lt;/PackageKey&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/File&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;File&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Attributes&amp;gt;Archive&amp;lt;/Attributes&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;CreationTime&amp;gt;2008-09-23T12:56:10-07:00&amp;lt;/CreationTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;LastAccessTime&amp;gt;2008-09-23T12:56:10-07:00&amp;lt;/LastAccessTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;LastWriteTime&amp;gt;2008-09-23T12:56:10-07:00&amp;lt;/LastWriteTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Name&amp;gt;PizzaOrderingService.pdb&amp;lt;/Name&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;PackageKey&amp;gt;PizzaOrderService\obj\Debug\PizzaOrderingService.pdb&amp;lt;/PackageKey&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/File&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;File&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Attributes&amp;gt;Archive&amp;lt;/Attributes&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;CreationTime&amp;gt;2008-09-23T12:56:10-07:00&amp;lt;/CreationTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;LastAccessTime&amp;gt;2008-09-23T12:56:10-07:00&amp;lt;/LastAccessTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;LastWriteTime&amp;gt;2008-09-23T12:56:10-07:00&amp;lt;/LastWriteTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Name&amp;gt;PizzaOrderService.csproj.FileListAbsolute.txt&amp;lt;/Name&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;PackageKey&amp;gt;PizzaOrderService\obj\Debug\PizzaOrderService.csproj.FileListAbsolute.txt&amp;lt;/PackageKey&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/File&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/Files&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;FullPath&amp;gt;C:\HandsOnLabs\Lab6\PizzaOrderingApplication\PizzaOrderService\obj\Debug&amp;lt;/FullPath&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Name&amp;gt;Debug&amp;lt;/Name&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/Directory&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/Directories&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Files /&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;FullPath&amp;gt;C:\HandsOnLabs\Lab6\PizzaOrderingApplication\PizzaOrderService\obj&amp;lt;/FullPath&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Name&amp;gt;obj&amp;lt;/Name&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/Directory&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;Directory&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Attributes&amp;gt;Normal&amp;lt;/Attributes&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Directories /&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;Files&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;File&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Attributes&amp;gt;Normal&amp;lt;/Attributes&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;CreationTime&amp;gt;2008-09-02T19:50:26-07:00&amp;lt;/CreationTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;LastAccessTime&amp;gt;2008-09-02T19:50:26-07:00&amp;lt;/LastAccessTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;LastWriteTime&amp;gt;2008-09-02T19:50:26-07:00&amp;lt;/LastWriteTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Name&amp;gt;AssemblyInfo.cs&amp;lt;/Name&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;PackageKey&amp;gt;PizzaOrderService\Properties\AssemblyInfo.cs&amp;lt;/PackageKey&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/File&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/Files&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;FullPath&amp;gt;C:\HandsOnLabs\Lab6\PizzaOrderingApplication\PizzaOrderService\Properties&amp;lt;/FullPath&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Name&amp;gt;Properties&amp;lt;/Name&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/Directory&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/Directories&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;Files&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;File&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Attributes&amp;gt;Normal&amp;lt;/Attributes&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;CreationTime&amp;gt;2008-09-02T19:50:26-07:00&amp;lt;/CreationTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;LastAccessTime&amp;gt;2008-09-02T19:50:26-07:00&amp;lt;/LastAccessTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;LastWriteTime&amp;gt;2008-09-02T19:50:26-07:00&amp;lt;/LastWriteTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Name&amp;gt;DataContracts.cs&amp;lt;/Name&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;PackageKey&amp;gt;PizzaOrderService\DataContracts.cs&amp;lt;/PackageKey&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/File&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;File&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Attributes&amp;gt;Normal&amp;lt;/Attributes&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;CreationTime&amp;gt;2008-09-09T15:33:48-07:00&amp;lt;/CreationTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;LastAccessTime&amp;gt;2008-09-09T15:33:48-07:00&amp;lt;/LastAccessTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;LastWriteTime&amp;gt;2008-09-09T15:33:48-07:00&amp;lt;/LastWriteTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;Name&amp;gt;PizzaOrderService.csproj&amp;lt;/Name&amp;gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;PackageKey&amp;gt;PizzaOrderService\PizzaOrderService.csproj&amp;lt;/PackageKey&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/File&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;File&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Attributes&amp;gt;Normal&amp;lt;/Attributes&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;CreationTime&amp;gt;2008-09-16T19:17:18-07:00&amp;lt;/CreationTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;LastAccessTime&amp;gt;2008-09-16T19:17:18-07:00&amp;lt;/LastAccessTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;LastWriteTime&amp;gt;2008-09-16T19:17:18-07:00&amp;lt;/LastWriteTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Name&amp;gt;PizzaOrderService.csproj.user&amp;lt;/Name&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;PackageKey&amp;gt;PizzaOrderService\PizzaOrderService.csproj.user&amp;lt;/PackageKey&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/File&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;File&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Attributes&amp;gt;Normal&amp;lt;/Attributes&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;CreationTime&amp;gt;2008-09-16T19:17:18-07:00&amp;lt;/CreationTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;LastAccessTime&amp;gt;2008-09-16T19:17:18-07:00&amp;lt;/LastAccessTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;LastWriteTime&amp;gt;2008-09-16T19:17:18-07:00&amp;lt;/LastWriteTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Name&amp;gt;PizzaOrderService.suo&amp;lt;/Name&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;PackageKey&amp;gt;PizzaOrderService\PizzaOrderService.suo&amp;lt;/PackageKey&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/File&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;File&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Attributes&amp;gt;Normal&amp;lt;/Attributes&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;CreationTime&amp;gt;2008-09-16T19:17:18-07:00&amp;lt;/CreationTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;LastAccessTime&amp;gt;2008-09-16T19:17:18-07:00&amp;lt;/LastAccessTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;LastWriteTime&amp;gt;2008-09-16T19:17:18-07:00&amp;lt;/LastWriteTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;Name&amp;gt;PizzaOrderService.xamlx&amp;lt;/Name&amp;gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;PackageKey&amp;gt;PizzaOrderService\PizzaOrderService.xamlx&amp;lt;/PackageKey&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/File&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;File&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Attributes&amp;gt;Archive&amp;lt;/Attributes&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;CreationTime&amp;gt;2008-09-23T12:43:42-07:00&amp;lt;/CreationTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;LastAccessTime&amp;gt;2008-11-04T13:21:57.6702032-08:00&amp;lt;/LastAccessTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;LastWriteTime&amp;gt;2008-11-04T13:21:57.674216-08:00&amp;lt;/LastWriteTime&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Name&amp;gt;Web.config&amp;lt;/Name&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;PackageKey&amp;gt;PizzaOrderService\Web.config&amp;lt;/PackageKey&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/File&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/Files&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;FullPath&amp;gt;C:\HandsOnLabs\Lab6\PizzaOrderingApplication\PizzaOrderService&amp;lt;/FullPath&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Name&amp;gt;PizzaOrderService&amp;lt;/Name&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;AuthenticationMethod&amp;gt;ClearText&amp;lt;/AuthenticationMethod&amp;gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Username /&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;VirtualPath&amp;gt;/&amp;lt;/VirtualPath&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/VirtualDirectory&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/VirtualDirectories&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;VirtualPath&amp;gt;/PizzaOrderService&amp;lt;/VirtualPath&amp;gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;WindowsAuthentication&amp;gt;false&amp;lt;/WindowsAuthentication&amp;gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/VirtualApplication&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;-&lt;/a&gt; &amp;lt;Website&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Name&amp;gt;Default Web Site&amp;lt;/Name&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/Website&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/Module&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/Modules&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Name&amp;gt;Default&amp;lt;/Name&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/Application&amp;gt;&lt;/p&gt;
&lt;p&gt;Oltre questo file viene preparata anche la sottodirectory archiveDir che contiene gli effettivi file che costituiscono l&amp;#39;applicazione.&lt;/p&gt;
&lt;p&gt;E&amp;#39; possibile poi importare nuovamente l&amp;#39;applicazione (modificandone alcuni dati per adattarli al server su cui si effettua l&amp;#39;import)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/14_ApplicationImport_Edit.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="484" alt="14_ApplicationImport_Edit" src="http://devlab.devleap.it/robertob/immagini/posts/DublinWindowsApplicationServer_DCEF/14_ApplicationImport_Edit_thumb.jpg" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Visto che il server di import sarà probabilmente diverso dal server da cui si è esportata l&amp;#39;applicazione è possibile modificare il nome dell&amp;#39;applicazione, l&amp;#39;application pool che la ospita e il path fisico in cui scompattare il file zip e su cui punterò la virtual directory.&lt;/p&gt;
&lt;p&gt;In un prossimo articolo vedremo un altro strumento di configurazione, a livello di macchina e i servizi che l&amp;#39;application server espone: XAML Activation, Durable Timer Service, Forwarding Service e andremo più nel dettaglio delle configurazioni.&lt;/p&gt;
&lt;p&gt;Roberto Brunetti&lt;/p&gt;&lt;img src="http://blogs.devleap.com/aggbug.aspx?PostID=18701" width="1" height="1"&gt;</content><author><name>rob</name><uri>http://blogs.devleap.com/members/rob.aspx</uri></author><category term=".NET 4 - VS 2010" scheme="http://blogs.devleap.com/articolidevleap/archive/tags/.NET+4+-+VS+2010/default.aspx" /></entry><entry><title>Visual Studio Team System 2010: primo contatto (parte 2)</title><link rel="alternate" type="text/html" href="http://blogs.devleap.com/articolidevleap/archive/2008/10/26/visual-studio-team-system-2010-primo-contatto-parte-2.aspx" /><id>http://blogs.devleap.com/articolidevleap/archive/2008/10/26/visual-studio-team-system-2010-primo-contatto-parte-2.aspx</id><published>2008-10-26T17.43.00Z</published><updated>2008-10-26T17.43.00Z</updated><content type="html">&lt;p&gt;Autore: &lt;a href="http://blogs.devleap.com/rob" target="_blank"&gt;Roberto Brunetti&lt;/a&gt; - &lt;a href="http://www.devleap.com/" target="_blank"&gt;DevLeap&lt;/a&gt;&amp;nbsp;&amp;nbsp; 
&lt;p&gt;Dopo la &lt;a href="http://blogs.devleap.com/articolidevleap/archive/2008/10/17/visual-studio-team-system-2010-primo-contatto.aspx"&gt;prima&lt;/a&gt; parte ecco un altra serie di informazioni su VSTS 2010. 
&lt;p&gt;In Visual Studio 2005 e 2008 il processo di compilazione è demandato a MSBUILD; in prima battuta , avendo un compilatore esterno, è possibile eseguire operazioni di compilazione esterne a Visual Studio e schedularne l’esecuzione. Con l’arrivo della parte server (Team Foundation Server 2005 è uscito 6 mesi dopo rispetto alla Team Suite di VS 2005) il motore di MSBUILD è stato integrato nel processo di Team Build: una build è una operazione di compilazione server-side. MSBuild, da sempre è estendibile, nel senso che possono essere create task custom per effettuare operazioni aggiuntive rispetto alla semplice complilazione. MSBuild quindi, oltre a prendere in pasto i file .proj (VB, C#, DB) e produrre il rispettivo output, ha consentito al motore del Build Server di effettuare operazioni come il recupero dei sorgenti dal repository, l’assegnazione di Label per indicare la fase di compilazione sui sorgenti, il lancio di unit test e la pubblicazione del compilato nella directory outputdrop. In pratica tutto il processo viene eseguito tramite task di MSBuild. 
&lt;p&gt;I file .targets di MSBuild che contengono le attività devono essere modificati a mano per inserire attività aggiuntive: questo costringe spesso alla chiusura del progetto (unload da visual studio) e un editing manuale del file .proj per agganciare attività esterne, come ad esempio puntare ad un file .targets custom per lanciare i comandi su stsadm.exe nel caso di sviluppo di una soluzione SharePoint. 
&lt;p&gt;In Visual Studio 2010 si cerca di andare oltre: tutto il processo di build sfrutta Workflow Foundation (in versione 4.0) e fornisce quindi un designer molto semplice e intuitivo per compilare gli step di compilazione effettivi. Il flusso può contare su una serie di activity custom sviluppate appositamente per effettuare le operazioni che oggi MSBuild consente di fare, oltre alla normale serie di activiy come ad esempio Sequence, CallExternalMethod per gestire il flusso di lavoro. 
&lt;p&gt;Questa una immagine del designer 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioteamsystem2010primocontattop_1046A/image.png"&gt;&lt;img style="BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-RIGHT-WIDTH:0px;" height="249" alt="image" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioteamsystem2010primocontattop_1046A/image_thumb.png" width="521" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;La sequenza delle attività viene impostate nel designer custom direttamente nella Build Definition. Nella Toolbox l’elenco delle activity out-of-the-box, che ovviamente può essere esteso con activity custom. 
&lt;p&gt;Si possono quindi usare le activity classiche (quelle che hanno scelto sono quelle sensate rispetto a cosa si fa nella build) ed esiste una activity per richiamare i “vecchi” task di MSBUILD consentendo di mantenere task custom create per l’attuale versione di Visual Studio. 
&lt;p&gt;Inoltre alcune activity possono essere chiamate in causa in modo condizionale rispetto al tipo di build che si fa: quindi il processo disegnato può essere lo stesso con alcune activity enabled solo se si fa un certo tipo di build (se siamo in continous integration oppure in build schedulata o ancora manuale possiamo definire nello stesso flusso cosa è attivo in ogni configurazione). 
&lt;p&gt;E’ veramente semplice gestire il tutto rispetto ai file .xml a mano. 
&lt;p&gt;Esistono poi due nuove tipologie di Build: Gated Check-in e ShelveSet Check-in. 
&lt;p&gt;Gated Check-in: ci si assicura di tutto prima di fare il check-in reale. Si stoppa il tutto se non va. E’ una pratica consolidata che non è però supportata nell’attuale versione e che parte dall’idea di invertire l’operazione di check-in e successiva compilazione. Prima si compila, si verificano le regole del Code Analysis, si lanciano i test e solo se tutto va a buon fine si esegue effettivamente il check-in. L’obiettivo è chiaro: evitare di mettere sotto SCC sorgenti che possono introdurre problemi. Ad oggi è possibile solo impostare alcune regole per fare check-in, ma costringono lo sviluppatore ad effettuare una operazione di CodeAnalysis e successivo lancio dei test prima di poter fare check-in. 
&lt;p&gt;Shelvset Build è l’altra nuiova opzione di build. Simile al gated come obiettivo, ma l’idea è questa: Si mettono le modifiche attuale in uno ShelveSet (gli shelveset sono presenti anche nella versione attuale di TFS e anche nella versione 2005) e tutto il processo di build lavora con i sorgenti dello shelveset. Al termine si fa il check-in se il codice non “rompe” la build. 
&lt;p&gt;Questa la finestra di gestione della build con le nuove modalità 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioteamsystem2010primocontattop_1046A/image_3.png"&gt;&lt;img style="BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-RIGHT-WIDTH:0px;" height="225" alt="image" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioteamsystem2010primocontattop_1046A/image_thumb_3.png" width="492" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;Nel caso di Gated Check-in o ShelveSet Check-in, a fronte di una operazione di check-in appare questa maschera con cui si può decidere se effettuare la compilazione e la validazione prima dell’effettivo check-in. 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioteamsystem2010primocontattop_1046A/image_4.png"&gt;&lt;img style="BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-RIGHT-WIDTH:0px;" height="149" alt="image" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioteamsystem2010primocontattop_1046A/image_thumb_4.png" width="291" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;Un’altra novità molto interessante è l’integrazione con Debugging History : il tool (si veda la sezione apposita) consente di registrare una operazione di debug in modo da poter rieseguire tutti i passi effettuati e tornare al punto dove sono stati trovati i problemi) senza dover rieseguire tutto il percorso a mano. Lo strumento memorizza anche tutte le informazioni che riguardano lo stato dell’applicazione durante la sessione di debug in modo da ripresentare la situazione completa e reale per poter investigare il tipo di problema risconstrato. 
&lt;p&gt;Build Controller: oggi è possibile configurare un solo build agent, il che costringe l’esecuzione del processo di build ad una sola macchina. In 2010 sono stati introdotti gli Agent Pool, gestiti da un Build Controller. In pratica si associa il Controller alla Build e il tutto viene fatto girare dai vari Agent configurati nel Pool. 
&lt;p&gt;Il Build Explorer presenta una nuova interfaccia che consente di effettuare le operazioni più comuni in modo semplice: ad esempio è possibile vedere il log completo direttamente da questa interfaccia senza aprire il famoso file di log .txt. Dal log è possibile accedere al codice che ha creato ad esempio un problema di compilazione. E’ possibile vedere le precedenti build dello stesso build type per analizzare la storia di una particolare build. 
&lt;p&gt;Ecco alcuni screenshot che si commentano da soli 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioteamsystem2010primocontattop_1046A/image_5.png"&gt;&lt;img style="BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-RIGHT-WIDTH:0px;" height="192" alt="image" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioteamsystem2010primocontattop_1046A/image_thumb_5.png" width="398" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Log espnso con indicazione di eventuali problemi&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioteamsystem2010primocontattop_1046A/image_6.png"&gt;&lt;img style="BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-RIGHT-WIDTH:0px;" height="361" alt="image" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioteamsystem2010primocontattop_1046A/image_thumb_6.png" width="320" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;Come accennato, se ci sono problemi di compilazione, per ogni riga in errore è presente un link nel log per saltare direttamente al codice che causa il problema. Ad oggi occorre vedere gli errori e poi cercare il problema manualmente. Inoltre, il puntatore al codice, ci porta alla versione dei sorgenti che è stata compilata, non a quella presente nel nostro workspace che nel frattempo potrebbe essere cambiata n volte. 
&lt;p&gt;Si può effettuare un Delete di una Build e decidere cosa fare rispetto a tutti i dati della Build: 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioteamsystem2010primocontattop_1046A/image_7.png"&gt;&lt;img style="BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-RIGHT-WIDTH:0px;" height="174" alt="image" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioteamsystem2010primocontattop_1046A/image_thumb_7.png" width="295" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;Anche nella maschera di gestione dei retention period si può decidere cosa fare non solo a livello di build come nella versione 2008, ma anche rispetto alle singole categorie di informazioni: 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioteamsystem2010primocontattop_1046A/image_8.png"&gt;&lt;img style="BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-RIGHT-WIDTH:0px;" height="221" alt="image" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioteamsystem2010primocontattop_1046A/image_thumb_8.png" width="520" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;In ogni caso, giustamente, anche se si cancella una build restano comunque alcune informazioni nel database marcate come deleted; questo per evitare di perdere le info legate ai work item. Si possono cancellare ma a riga di comando: deve essere una richiesta esplicita. 
&lt;p&gt;Si possono impostare permessi molto granulari su chi può vedere i dati a livello di Build. 
&lt;p&gt;&lt;b&gt;Web Access&lt;/b&gt; 
&lt;p&gt;Con il SP1 del 2008 è uscito il prodotto ufficiale (dopo l’acquisizione di TeamPlain). 
&lt;p&gt;La versione 2010 fa un salto in avanti sulla user interface sfruttando AJAX: l’interfaccia risulta più user friendly e veloce da utilizzare. 
&lt;p&gt;Fra le novità, la visualizzazione della gerarchia di workitem che rispetta la gerarchia di TFS, la possibilità di fare bulk edit di una proprietà da applicare ad una query di work item o a una multi-selezione di work-item. Quest’ultimo punto è molto utile quando occorre ad esempio riassegnare una serie di task ad un altro membro del team. Questa interfaccia risulta più funzionale anche rispetto ad Excel che oggi è lo strumento principe per fare bulk load di informazioni. Ecco la maschera di gestione del Bulk Edit in cui si assegna l’Area Northwind\UI e lo Stato di Resolved ad una serie di work item eselezionati 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioteamsystem2010primocontattop_1046A/image_9.png"&gt;&lt;img style="BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-RIGHT-WIDTH:0px;" height="229" alt="image" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioteamsystem2010primocontattop_1046A/image_thumb_9.png" width="433" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;Se ci sono errori nel bulk edit si vede può controllare il progresso e eventuali problemi sui singoli work item (ad esempio la modifica non può essere applicata perchè lo stato non consente quel tipo di modifica) 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioteamsystem2010primocontattop_1046A/image_10.png"&gt;&lt;img style="BORDER-TOP-WIDTH:0px;BORDER-LEFT-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-RIGHT-WIDTH:0px;" height="131" alt="image" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioteamsystem2010primocontattop_1046A/image_thumb_10.png" width="287" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;In Excel, seppur comodissimo, occorre invece eseguire la modifica item per item (o con un find/replace...sempre molto pericoloso). 
&lt;p&gt;Molte delle componenti del Web Access sono costituite da Web Part: questo consente di riutilizzare parti della user interface in applicazioni custom basate su SharePoint o ASP.NET. A proposito di SharePoint, quando si crea un nuovo team project si può fare anche provisioning su SharePoint di alcune feature per creare la dashboard da customizzare. 
&lt;p&gt;&lt;b&gt;TFS Migration &amp;amp; Sync&lt;/b&gt; 
&lt;p&gt;Migration:l’obiettivo è portare un altro sistema in TFS. Gli strumenti effettuano una importazione dei dati da altri sistemi. Esistono già strumenti di questo tipo per TFS 2008, primo fra tutti, lo strumento di migrazione da Source Safe. 
&lt;p&gt;Nella nuova versione però, nascono nuovi strumenti nativi che consentono di sincronizzare il contenuto di TFS con altri prodotti (ad esempio ClearCase) per consentire l’utilizzo di entrambi gli strumenti in contemporanea. Si pensi ad esempio alla migrazione di cui sopra: sto utilizzando un sistema di bug tracking, decido di passare a TFS, ma per un periodo di tempo dovrò ancora usare il “vecchio” sistema e tenere allineate le informazioni. 
&lt;p&gt;Su CodePlex trovate alcuni toolkit per applicare alcune di queste funzionalità anche a TFS 2008. 
&lt;p&gt;Molte informazioni che trovate in questo mio articolo e alcuni screenshot arrivano direttamente dai video che sono stati pubblicati nella Team System Week Videos di fine settembre 2008: &lt;a href="http://channel9.msdn.com/posts/VisualStudio/Visual-Studio-Team-System-2010-Week-on-Channel-9/"&gt;http://channel9.msdn.com/posts/VisualStudio/Visual-Studio-Team-System-2010-Week-on-Channel-9/&lt;/a&gt;. 
&lt;p&gt;Sono appena arrivato a Los Angeles per Microsoft PDC 2008: se ci saranno altre informazioni in questi giorni su VSTS 2010 le includo nel prossimo articolo già previsto per la prossima settimana. 
&lt;p&gt;Allego tutti i miei post sulla versione 2005 e 2008 di VSTS/TFS come puntatori che spero siano utili 
&lt;p&gt;&lt;b&gt;Architect&lt;/b&gt;. 
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2005/12/29/6428.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2005/12/29/6428.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt;&lt;/b&gt; 
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2007/10/15/visual-studio-team-system-2008-architect-power-tools.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2007/10/15/visual-studio-team-system-2008-architect-power-tools.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://www.devleap.com/document.aspx?id=3837"&gt;&lt;b&gt;http://www.devleap.com/document.aspx?id=3837&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2006/09/24/14243.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2006/09/24/14243.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2006/01/27/6584.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2006/01/27/6584.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2005/12/29/6428.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2005/12/29/6428.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2005/09/12/5706.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2005/09/12/5706.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;&lt;b&gt;Developer e Tester&lt;/b&gt; 
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2008/09/10/vsts-2008-sp1-web-test.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2008/09/10/vsts-2008-sp1-web-test.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2007/08/21/visual-studio-2008-for-mobile-dev-e-non-solo.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2007/08/21/visual-studio-2008-for-mobile-dev-e-non-solo.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2007/07/16/workflow-custom-activity-e-vsts-unit-test.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2007/07/16/workflow-custom-activity-e-vsts-unit-test.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2005/12/30/6434.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2005/12/30/6434.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2005/09/12/5705.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2005/09/12/5705.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2006/01/30/6608.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2006/01/30/6608.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;&lt;b&gt;Database Edition&lt;/b&gt; 
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2007/08/20/vsts-for-db-pro-power-tools.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2007/08/20/vsts-for-db-pro-power-tools.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2007/07/28/vsts-for-db-pro-service-release-1.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2007/07/28/vsts-for-db-pro-service-release-1.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2007/02/02/vsts-for-db-pro-aggiunta-e-successivo-refactor-di-un-campo.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2007/02/02/vsts-for-db-pro-aggiunta-e-successivo-refactor-di-un-campo.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2007/02/02/vsts-for-db-pro-schema-update-per-aggiunta-campo.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2007/02/02/vsts-for-db-pro-schema-update-per-aggiunta-campo.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2007/02/01/vsts-for-db-pro-schema-update-con-merge-replication.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2007/02/01/vsts-for-db-pro-schema-update-con-merge-replication.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2006/12/25/15649.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2006/12/25/15649.aspx&lt;/b&gt;&lt;/a&gt; 
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2008/09/17/microsoft-174-visual-studio-team-system-2008-database-edition-gdr-august-ctp.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2008/09/17/microsoft-174-visual-studio-team-system-2008-database-edition-gdr-august-ctp.aspx&lt;/b&gt;&lt;/a&gt; 
&lt;p&gt;&lt;b&gt;TFS&lt;/b&gt; 
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2008/09/09/tfs-2008-sp1-problem.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2008/09/09/tfs-2008-sp1-problem.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2008/09/09/tfs-2008-sp1-problem.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2008/09/09/tfs-2008-sp1-problem.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2008/09/06/visual-studio-team-system-web-access-2008-sp1-power-tool.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2008/09/06/visual-studio-team-system-web-access-2008-sp1-power-tool.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2007/11/20/team-foundation-server-2008-upgrade.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2007/11/20/team-foundation-server-2008-upgrade.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2005/09/03/5645.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2005/09/03/5645.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2005/12/05/6330.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2005/12/05/6330.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;&lt;a href="http://blogs.devleap.com/rob/archive/2006/03/30/7085.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2006/03/30/7085.aspx&lt;/b&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Roberto Brunetti&lt;/p&gt;&lt;img src="http://blogs.devleap.com/aggbug.aspx?PostID=18665" width="1" height="1"&gt;</content><author><name>rob</name><uri>http://blogs.devleap.com/members/rob.aspx</uri></author><category term=".NET 4 - VS 2010" scheme="http://blogs.devleap.com/articolidevleap/archive/tags/.NET+4+-+VS+2010/default.aspx" /></entry><entry><title>Visual Studio Team System 2010: Primo Contatto</title><link rel="alternate" type="text/html" href="http://blogs.devleap.com/articolidevleap/archive/2008/10/17/visual-studio-team-system-2010-primo-contatto.aspx" /><id>http://blogs.devleap.com/articolidevleap/archive/2008/10/17/visual-studio-team-system-2010-primo-contatto.aspx</id><published>2008-10-17T16.45.00Z</published><updated>2008-10-17T16.45.00Z</updated><content type="html">&lt;p&gt;Autore: &lt;a href="http://blogs.devleap.com/rob" target="_blank"&gt;Roberto Brunetti&lt;/a&gt; - &lt;a href="http://www.devleap.com/" target="_blank"&gt;DevLeap&lt;/a&gt; 
&lt;p&gt;Questo articolo ripercorre alcuni miei appunti e le prime impressioni di utilizzo di Visual Studio Team System 2010. Sto usando un progetto di esempio per analizzare il prodotto prima di portare la nostra famosa applicazione Estates Management sotto VSTS 2010. 
&lt;p&gt;Visual Studio Team System venti-dieci (come viene chiamato affettuosamente) porta con se molte novità sia per la versione Architect che per la versione Tester. Non meno numerose sono le nuove funzionalità della parte Team Foundation Server. &lt;br /&gt;Da quello che si evince dalle conferenze stampa la parte più importante delle novità riguarda l’edizione Architect, sia per quanto riguarda le modalità di lavoro del team ovvero una maggiore singergia fra i componenti, sia per quanto rigurda l’introduzione di strumenti di modellazione UML che si aggiungono agli attuali DSL. 
&lt;p&gt;&lt;b&gt;Democratize: everybody has a chance to play&lt;/b&gt; 
&lt;p&gt;Quello che accade spesso oggi, anche nei progetti che ho seguito personalmente, è la quasi totale divisione dei compiti fra architetti e gli altri membri del team: solitamente all’inizio della progettazione gli architetti si chiudono in una stanza e producono una serie di diagrammi architetturali. E’ vero che già oggi, se questi diagrammi sono prodotti con la Architect Edition, è possibile implementare le componenti applicative partendo dal diagramma e grazie alle estensioni dei power tools è possibile creare progetti di tipo ASP.NET, Windows e class library arrivando alla solution completa dei progetti e delle reference fra di essi. Per esempio, partendo dal diagramma seguente è possibile implementare con un solo colpo di mouse l’applicazione ASP.NET, l’applicazione windows client e le due dll rappresentate in questo estratto del diagramma completo. 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2010PrimoContatto_1079E/clip_image001.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="358" alt="clip_image001" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2010PrimoContatto_1079E/clip_image001_thumb.jpg" width="430" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;Si veda il &lt;a href="http://blogs.devleap.com/rob/archive/2007/10/15/visual-studio-team-system-2008-architect-power-tools.aspx"&gt;post completo sui Power Tools&lt;/a&gt;. 
&lt;p&gt;L’interazione fra il diagramma applicativo e il codice reale è presente anche nella configurazione delle applicazioni: sul client windows e sull’applicazione web, per proseguire con l’estratto del nostro esempio, la configurazione effettuata dagli architetti sui Settings &amp;amp; Constraint si riflette sulle effettive configurazioni presenti all’interno dei rispettivi file .config. 
&lt;p&gt;In Visual Studio Team System 2010 la sincronizzazione e quindi la collaborazione fra il “disegno” e il codice reale (e quindi fra Architect e Developer) viene effettuata a più livelli. Ad esempio il nuovo &lt;b&gt;Layer Diagram&lt;/b&gt; consente di visualizzare le varie componenti applicative nei layer definiti per l’applicazione. L’architetto e/o il developer possono così avere una rappresentazione più concreta di quali elementi sono compresi in quali layer. 
&lt;p&gt;Ecco un esempio di Layer Diagram per una applicazione di esempio: 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2010PrimoContatto_1079E/clip_image003.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="305" alt="clip_image003" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2010PrimoContatto_1079E/clip_image003_thumb.jpg" width="363" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;Nella toolbox ci sono solo Layer e Dependency che consentono di definire i layer applicativi e i flussi delle chiamate fra layer. Si può partire da zero oppure da una applicazione esistente (ad esempio da diagramma dei namaspace, più avanti) trascinando un namespace e portandolo sul layer effettivo. Si può fare poi Show Dependency per vedere le dependency fra le classi dei namespace rappresentati nel diagramma senza dover ricreare i percorsi. Con questo diagramma quindi possiamo rappresentare velocemente i vari componenti applicativi suddividendoli nei layer logici e verificare su una applicazione esistente quali sono le interazioni fra le classi. 
&lt;p&gt;Il flusso delle chiamate definisce anche le regole di chiamata fra layer: ad esempio, se il Presentation Layer ha un flusso possibile solo con il Business Layer, non dovremmo permettere allo sviluppatore di fare una reference verso il Data Access Layer e utilizzare direttamente le classi di accesso ai dati. Tramite la funzione Validate All è possibile eseguire questi controlli senza dover analizzare il codice. In pratica si controlla che le classi reali non facciano chiamate che non sono permesse dalle dependency: trovo questo strumento importantissimo per effettuare verifiche sulle applicazioni esistenti e per rappresentare graficamente una applicazione esistente ricavandone le idee architetturali che spesso non sono state documentate (forse ho avuto sfiga, ma nei progetti esistenti su cui ho messo le mani a posteriori, la documentazione è sempre stato un problema..non so se capita anche a voi J). Si possono anche impostare regole di compilazione per MSBuild per evitare una compilazione che non rispetti le corrette chiamate fra layer. E’ possibile fare queste verifiche anche sul Build Server (quindi anche senza Visual Studio) inserendo un tag &amp;lt;validate Include=”diagramma.Layer”&amp;gt; che punta al diagramma da controllare. E’ un FxCop per Architect J. 
&lt;p&gt;I diagrammi si possono Copy&amp;amp;Paste ovunque oppure esportare (stanno decidendo dove: sembra Visio di sicuro) per creare documentazione elettronica senza sforzo. 
&lt;p&gt;Il layer diagram è accessibile anche dal codice e vice versa, ovvero è possibile conoscere la posizione del codice che sto vedendo rispetto ai layer oppure scendere nel dettaglio di una classe (nel codice della classe) partendo dalla rappresentazione nel layer diagram. 
&lt;p&gt;&lt;b&gt;UML&lt;/b&gt; 
&lt;p&gt;Un’altra novità di rilievo della versione Architect è il &lt;b&gt;supporto a UML&lt;/b&gt; che in molti hanno lamentano nella versione 2005 e 2008 di Visual Studio Team System Architect Edition. L’idea è poter approcciare la definizione dell’architettura Top-Down oppure Bottom-Up. 
&lt;p&gt;Se si guarda la soluzione dall’altro, sono disponibili 5 designer UML (almeno secondo le previsioni attuali) per rappresentare il livello logico di una applicazione; se invece si guarda la soluzione dal basso, restano più che validi i DSL che, essendo più concreti e più specializzati, aderiscono meglio alla rappresentazione reale. L’idea è quindi non abbandonare DSL, ma creare la formula magica: UML + DSL == Better Code. La cosa interessante e che i diagrammi sono “agganciabili” ovvero si può partire dal diagramma logico in UML (ad esempio il sequence diagram) per scendere nel codice reale con un semplice click del mouse. Ad una modifica del codice reale, supponiamo per effettuare una chiamata ad una nuova classe, il sequence diagram si aggiorna per rappresentare questa interazione. 
&lt;p&gt;Per quanto riguarda UML (2.0 e 1.1) è importante comprendere la connessione rispetto ai DSL che stanno sotto. Addirittura, i designer UML sono stati creati con il DSK Toolkit. Quindi i DSL tool esistono ancora e anzi ne viene incoraggiato l’utilizzo per modellare il proprio dominio creando i DSL custom. 
&lt;p&gt;Hanno deciso di “tornare” a UML perchè è quello che la gente usa. La prima versione di VSTS puntava invece a rappresentare in modo aderente alla realtà del progetto l’applicazione, i logical datacenter e il deploy relativo. Probabilmente non saranno 100% standard perchè nessuno lo è: cercheranno di coprire i livelli (come sapete il supporto allo “standard” UML viene indicato come compliance ad un determinato livello) 
&lt;p&gt;Nella prima versione (2010) ci saranno questi 5 diagrammi UML: 
&lt;p&gt;1. Use Case 
&lt;p&gt;2. Component 
&lt;p&gt;3. Activity 
&lt;p&gt;4. Class 
&lt;p&gt;5. Sequence 
&lt;p&gt;Tutti questi strumenti hanno una migliore integrazione con il codice: ad esempio sto scrivendo o analizzando questo pezzo di codice e posso sapere in che punto mi trovo rispetto ai diagrammi. 
&lt;p&gt;Resta l’idea che non viene consigliata una modalità (fra top-down o bottom-up): ognuno si può muovere come preferisce rispetto al suo modo di lavorare. 
&lt;p&gt;Rapporto con Visio: Visio è il prodotto più usato al mondo per far modeling UML quindi sarà possibile importare i diagrammi. 
&lt;p&gt;&lt;b&gt;Top Down Approach (parto con UML)&lt;/b&gt; 
&lt;p&gt;Il nuovo Model Explorer Windows consente di vedere e gestire i vari modelli. I diagrammi UML si aggiungono alla solution: ognuno ha una estensione diversa gestita anche da TFS per centralizzare i diagrammi e gestirne il versioning. 
&lt;p&gt;Ecco qualche screen-shot dei designer UML. 
&lt;p&gt;1) Use Case 
&lt;p&gt;a. Actor e i vari Use Case 
&lt;p&gt;b. Si connettono (association) gli actor ai vari use case 
&lt;p&gt;c. Si possono fare le include di un uc in un altro uc 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2010PrimoContatto_1079E/clip_image005.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="342" alt="clip_image005" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2010PrimoContatto_1079E/clip_image005_thumb.jpg" width="385" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;2) Activity Diagram 
&lt;p&gt;a. Descrrive il flusso dei dati (i processi): si mettono gli step e si connettono in sequenza 
&lt;p&gt;b. Nel Model Explorer si vedono le componenti degli altri diagrammi per poter creare legami fra di essi. 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2010PrimoContatto_1079E/clip_image007.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="329" alt="clip_image007" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2010PrimoContatto_1079E/clip_image007_thumb.jpg" width="379" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;3) Sequence Diagram 
&lt;p&gt;a. Si può fare reverse engineer dal codice 
&lt;p&gt;b. Si disegnano le seguenze 
&lt;p&gt;c. Il diagramma resta sincronizzato con il codice (come vedremo più avanti), quindi a fronte di una nuova chiamata scritta nel metodo, il diagramma presenta un nuovo passo all’interno della sequenza&lt;br /&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2010PrimoContatto_1079E/clip_image009.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="343" alt="clip_image009" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2010PrimoContatto_1079E/clip_image009_thumb.jpg" width="329" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;4) Component Diagram 
&lt;p&gt;a. I Component non rappresentano elementi fisici (potranno poi essere DLL o EXE o composizioni di questi, ma a questo livello non ci interessa) 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2010PrimoContatto_1079E/clip_image011.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="341" alt="clip_image011" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2010PrimoContatto_1079E/clip_image011_thumb.jpg" width="441" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;b. Si mettono poi le interfacce e si connettono i vari componenti sempre utilizzando le informazioni del Model Explorer.&lt;br /&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2010PrimoContatto_1079E/clip_image013.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="323" alt="clip_image013" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2010PrimoContatto_1079E/clip_image013_thumb.jpg" width="434" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;5) Logical Class Diagram 
&lt;p&gt;a. Lavora con il Class Diagram .NET che rappresenta il fisico 
&lt;p&gt;b. Si trascinano gli elementi definiti negli altri diagrammi 
&lt;p&gt;c. Si definiscono le operazioni e gli attributi 
&lt;p&gt;d. Si torna nel .sequence e si legano le “cose reali” 
&lt;p&gt;e. Si possono fare “cose ereditate” (e il designer mostra il tutto) 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2010PrimoContatto_1079E/clip_image015.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="337" alt="clip_image015" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2010PrimoContatto_1079E/clip_image015_thumb.jpg" width="381" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;In questo ultimo digramma si vede l’interfaccia di pagamento derivata nel sistema di pagamento specifico per l’applicazione. 
&lt;p&gt;&lt;b&gt;Botton Up (parto dal codice)&lt;/b&gt; 
&lt;p&gt;L’idea è che quasi sempre ci sono cose già fatte: anche quando si parte con un progetto nuovo magari ci sono esempi fatti o pezzi già pronti realizzati per prova o altri componenti esistenti da utilizzare. 
&lt;p&gt;Il diagramma con estensione.dgml consente di iniziare a comprendere una applicazione esistente. Per creare il diagramma in modo semplice si utilizza l’Architecture Explorer che mostra tutte le classi nella solution divisi per componente e namespace. Ad esempio, partendo da questa situazione esistente nella solution 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2010PrimoContatto_1079E/clip_image017.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="351" alt="clip_image017" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2010PrimoContatto_1079E/clip_image017_thumb.jpg" width="440" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;E trascindando le classi di un namespace (volendo anche tutte le classi della solution) si ottiene la rappresentazione delle classi e l’interazione fra di esse all’interno di questo 
&lt;p&gt;E si ottiene questo 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2010PrimoContatto_1079E/clip_image019.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="343" alt="clip_image019" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2010PrimoContatto_1079E/clip_image019_thumb.jpg" width="242" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;A parte una inutile ragnatela, pensiero che colpisce subito appena il diagramma viene rappresentato, basta prendere una classe, cliccarci sopra e iniziare ad esplorare le interazioni fra le classi in modo semplice e intuitivo: pensate sempre a cosa vorrebbe dire entrare nel codcie di ogni classe e di ogni metodo per vedere quali sono le chiamate effettuate, e ancoara più difficile, sapere da quali componenti viene chiamata la classe in oggetto: da sempre l’object explorer ci può dare una mano, ma vedere graficamente “la ragnatela” è decisamente più semplice e intuitivo. 
&lt;p&gt;Da questo diagramma si possono far partire diversi Analyzer che analizzano appunto il diagramma stesso per individuare, ad esempio, i riferimenti circolari, piuttosto che le dipendenze fra le chiamate; quest’ultimo individua le classi (volendo raggruppatoe per namespace) e le chiamate effettuate. Ecco un esempio: 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2010PrimoContatto_1079E/clip_image021.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="333" alt="clip_image021" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2010PrimoContatto_1079E/clip_image021_thumb.jpg" width="287" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;Diventa più semplice capire l’applicazione esistente, vederne i dettagli (da ogni classe si può andare a visualizzare il codice, vedi prossima immagine), analizzare le dipendenze e le eventuali anomalie sulle chiamate senza dover per forza vedere il codice (che magari è stato scritto in sanscrito J). 
&lt;p&gt;Il dettaglio di ogni classe dentro il namespace e il codice è visibile facendo un semplice doppio click. 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2010PrimoContatto_1079E/clip_image023.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="309" alt="clip_image023" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2010PrimoContatto_1079E/clip_image023_thumb.jpg" width="415" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;Quest’ultima immagine non ha molto senso; era assolutamente chiaro cosa volesse dire andare a vedere il codice con un doppio click, ma averla inserita ci consente di capire che facendo ancora una volta una semplice operazione con il mouse possiamo generare il Sequence Diagram (a partire da qualunque metodo). 
&lt;p&gt;Questo il Seguence Diagram del metodo createNewOrderButton_Click 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2010PrimoContatto_1079E/clip_image025.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="328" alt="clip_image025" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2010PrimoContatto_1079E/clip_image025_thumb.jpg" width="387" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;Se nell’approccio Top-Down il Sequence Diagram era la base di partenza per poi scrivere il codice, avendo una applicazione esistente è facile percorrere il percorso inverso. 
&lt;p&gt;E’ ottima questa sincronizzazione (e forma di reverse engineering) anche per imparare a creare Sequence Diagram: ad esempio metto una chiamata ad un’altra classe nel codice e vedo come avrei dovuto fare il Sequence Diagram. E’ ovvio che sarebbe bene fare il contrario, il sequence diagram nasce proprio per rappresentare i flussi in modo astratto dal codcie, ma avere entrambe le possibilità è sicuramente un plus. 
&lt;p&gt;Ovviamente dal sequence diagram si può tornare codice del metodo rappresentato. 
&lt;p&gt;Dal Sequence Diagram si può anche produrre il Class Diagram e sincronizzarlo oppure effettuare una Create Method per aggiungere un metodo reale alla classe rappresentata. 
&lt;p&gt;Per questa prima parte direi che è tutto. Ci sentiamo presto per vedere le novità sulla parte tester, build, manual testing e le novità della parte di gestione del progetto come work-item gerarchici. 
&lt;p&gt;Molte informazioni che trovate in questo mio articolo e alcuni screenshot arrivano direttamente dai video che sono stati pubblicati nella Team System Week Videos di fine settembre 2008: &lt;a href="http://channel9.msdn.com/posts/VisualStudio/Visual-Studio-Team-System-2010-Week-on-Channel-9/"&gt;http://channel9.msdn.com/posts/VisualStudio/Visual-Studio-Team-System-2010-Week-on-Channel-9/&lt;/a&gt;. 
&lt;p&gt;Allego anche tutti i miei post sulla versione 2005 e 2008 di VSTS/TFS come puntatori che spero siano utili 
&lt;p&gt;&lt;b&gt;Architect&lt;/b&gt;. 
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2005/12/29/6428.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2005/12/29/6428.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt;&lt;/b&gt; 
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2007/10/15/visual-studio-team-system-2008-architect-power-tools.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2007/10/15/visual-studio-team-system-2008-architect-power-tools.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://www.devleap.com/document.aspx?id=3837"&gt;&lt;b&gt;http://www.devleap.com/document.aspx?id=3837&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2006/09/24/14243.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2006/09/24/14243.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2006/01/27/6584.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2006/01/27/6584.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2005/12/29/6428.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2005/12/29/6428.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2005/09/12/5706.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2005/09/12/5706.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;&lt;b&gt;Developer e Tester&lt;/b&gt; 
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2008/09/10/vsts-2008-sp1-web-test.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2008/09/10/vsts-2008-sp1-web-test.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2007/08/21/visual-studio-2008-for-mobile-dev-e-non-solo.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2007/08/21/visual-studio-2008-for-mobile-dev-e-non-solo.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2007/07/16/workflow-custom-activity-e-vsts-unit-test.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2007/07/16/workflow-custom-activity-e-vsts-unit-test.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2005/12/30/6434.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2005/12/30/6434.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2005/09/12/5705.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2005/09/12/5705.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2006/01/30/6608.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2006/01/30/6608.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;&lt;b&gt;Database Edition&lt;/b&gt; 
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2007/08/20/vsts-for-db-pro-power-tools.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2007/08/20/vsts-for-db-pro-power-tools.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2007/07/28/vsts-for-db-pro-service-release-1.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2007/07/28/vsts-for-db-pro-service-release-1.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2007/02/02/vsts-for-db-pro-aggiunta-e-successivo-refactor-di-un-campo.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2007/02/02/vsts-for-db-pro-aggiunta-e-successivo-refactor-di-un-campo.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2007/02/02/vsts-for-db-pro-schema-update-per-aggiunta-campo.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2007/02/02/vsts-for-db-pro-schema-update-per-aggiunta-campo.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2007/02/01/vsts-for-db-pro-schema-update-con-merge-replication.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2007/02/01/vsts-for-db-pro-schema-update-con-merge-replication.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2006/12/25/15649.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2006/12/25/15649.aspx&lt;/b&gt;&lt;/a&gt; 
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2008/09/17/microsoft-174-visual-studio-team-system-2008-database-edition-gdr-august-ctp.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2008/09/17/microsoft-174-visual-studio-team-system-2008-database-edition-gdr-august-ctp.aspx&lt;/b&gt;&lt;/a&gt; 
&lt;p&gt;&lt;b&gt;TFS&lt;/b&gt; 
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2008/09/09/tfs-2008-sp1-problem.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2008/09/09/tfs-2008-sp1-problem.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2008/09/09/tfs-2008-sp1-problem.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2008/09/09/tfs-2008-sp1-problem.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2008/09/06/visual-studio-team-system-web-access-2008-sp1-power-tool.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2008/09/06/visual-studio-team-system-web-access-2008-sp1-power-tool.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2007/11/20/team-foundation-server-2008-upgrade.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2007/11/20/team-foundation-server-2008-upgrade.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2005/09/03/5645.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2005/09/03/5645.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2005/12/05/6330.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2005/12/05/6330.aspx&lt;/b&gt;&lt;/a&gt;&lt;b&gt; &lt;/b&gt;
&lt;p&gt;• &lt;a href="http://blogs.devleap.com/rob/archive/2006/03/30/7085.aspx"&gt;&lt;b&gt;http://blogs.devleap.com/rob/archive/2006/03/30/7085.aspx&lt;/b&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Roberto Brunetti&lt;/p&gt;&lt;img src="http://blogs.devleap.com/aggbug.aspx?PostID=18658" width="1" height="1"&gt;</content><author><name>rob</name><uri>http://blogs.devleap.com/members/rob.aspx</uri></author><category term=".NET 4 - VS 2010" scheme="http://blogs.devleap.com/articolidevleap/archive/tags/.NET+4+-+VS+2010/default.aspx" /></entry><entry><title>ADO.NET Synchronization services</title><link rel="alternate" type="text/html" href="http://blogs.devleap.com/articolidevleap/archive/2008/05/14/ado-net-synchronization-services.aspx" /><id>http://blogs.devleap.com/articolidevleap/archive/2008/05/14/ado-net-synchronization-services.aspx</id><published>2008-05-14T09.09.38Z</published><updated>2008-05-14T09.09.38Z</updated><content type="html">&lt;p&gt;Articolo&lt;b&gt; Intro to ADO.NET Sync Services&lt;/b&gt; pubblicato su Computer Programming di Marzo 2008.&lt;br /&gt;Autore: Roberto Brunetti &lt;p&gt;Con l’uscita del Framework .NET 3.5 Microsoft propone il primo tassello di un nuovo framework di sincronizzazione informazioni. Questo primo assaggio, denominato ADO.NET Synchronization Services, semplifica la scrittura di codice per replicare/sincronizzare strutture e dati di un database SQL Server verso client remoti che necessitano di lavorare offline.  &lt;p&gt;L’esigenza di replicare il database o porzioni di esso nasce con l’avvento dei portatili e dei palmari a metà degli anni 90: si pensi al classico scenario di raccolta ordini sul campo in cui il venditore scarica sul suo pc/palmare il listino prodotti (tabelle in solo download), inserisce gli ordini su un database locale (in tabelle di solo upload) e magari può modificare alcune informazioni della tabella clienti preventivamente scaricata e successivamente sincronizzata con il database centrale.  &lt;p&gt;Le prime implementazioni su palmare si sono appoggiate ai meccanismi di replica nativi di SQL CE che, sin dalla sua prima versione, propone due tecniche di replica dei dati: Remote Data Access (RDA) e Merge Replication. La prima tecnica consente allo sviluppatore di indicare la query da eseguire server-side e la tabella in locale in cui accogliere i dati tramite il metodo Pull. Una volta scaricati i dati SQL CE tiene monitorate le modifiche effettuate ai dai in locale e consente con un semplice metodo (Push) di inviare al server solo tali modifiche. Tutte le operazioni vengono avviate da codice e non è necessario ne modificare la struttura ne configurare in modo particolare il database server. Diametralmente opposta come approccio troviamo la seconda tecnica nativa di sincronizzazione dei dati presente sia in SQL CE 2.0 che in SQL Server 2000: la Merge Replication richiede una configurazione del database server che comprende la pubblicazione degli oggetti database da replicare con i client, le modalità di replica, l’assegnazione di range per i campi identity, la definizione dei profili di replica (ad esempio il tipo di compressione o il numero di modifiche da inviare in singoli chunk transazionali al client).  &lt;p&gt;Occupandomi di sviluppo mobile dal 1997 ho lavorato molto sia con RDA, scelta preferita nelle casistiche più semplici, sia con la Merge Replication per scenari più “corposi”. Le innumerevoli possibilità di configurazione della Merge Replication la rendono adatta a tutti gli scenari possibili a patto di avere SQL Server (dalla 2000 in poi) come database server e un server IIS che faccia da tramite http per le richieste che arrivano dal client.  &lt;p&gt;In pratica la Merge Replication  &lt;p&gt;· E’ una tecnologia focalizzata sulla configurazione del server  &lt;p&gt;· E’ una tecnologia che fornisce soluzioni end-to-end  &lt;p&gt;· Non è developer-oriented: il codice lato client indica solamente i parametri da usare per quel particolare tipo di client e connessione  &lt;p&gt;· E’ orientata allo scambio di dati e non all’utilizzo di servizi  &lt;p&gt;Per questi motivi il framework .NET in versione 3.5 propone ADO.NET Sync Services, meccanismo più leggero e più gestibile da codice rispetto alla Merge Replication che meglio si adatta a scenari semplici in cui lo sviluppatore, con un impatto minimo sulla struttura delle tabelle, può controllare la replica dei dati. In pratica questa tecnologia consente di avere una cache locale dei dati sul client e i metodi per poter sincronizzare lo store locale con il database server.  &lt;p&gt;I punti fondamentali da chiarire subito sono i seguenti  &lt;p&gt;· La tecnologia si basa su ADO.NET e quindi può lavorare con varie tipologie di database server side  &lt;p&gt;· Lato client viene usato SQL CE 3.5 come store delle informazioni  &lt;p&gt;· Visual Studio 2008 espone wizard e designer per semplificare lo sviluppo  &lt;p&gt;· Il deployment può essere effettuato con ClickOnce  &lt;p&gt;· L’impatto sul server è minimo  &lt;p&gt;· Nativamente lavora single-tier in client-server oppure multi-tier in client-server  &lt;p&gt;· Non è incluso in questa prima versione il supporto nel .NET Compact Framework 3.5  &lt;p&gt;· Il tutto è estendibile per lavorare via servizi ASMX o WCF  &lt;p&gt;Iniziamo con lo schema architetturale delle varie componenti.  &lt;p&gt;Lato client troviamo le classi denominate Client Synchroniztion Provider che si appoggiano al Synchronization Agent per la sincronizzazione delle informazioni. Il Sync Agent controlla la definizione e la modalità di sincronizzazione delle singole tabelle (Sync Table). Al lancio della sincronizzazione il Sync Agent contatta la parte server (per default in-process nella classica topologia client-server) la quale lancia le query sul database per recuperare i dati modificati dall’ultima sincronizzazione e modificare i dati inviati dal client.  &lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/ADO.NETSynchronizationservices_9BFF/clip_image002.gif"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="377" alt="clip_image002" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/ADO.NETSynchronizationservices_9BFF/clip_image002_thumb.gif" width="543" border="0" /&gt;&lt;/a&gt;  &lt;p&gt;Come si può notare dalla slide del nostro corso vengono utilizzati 3 assembly .NET in forma di dll  &lt;p&gt;· Microsoft.Synchronization.Data.SqlServerCe.dll: è la dll utilizzata lato client per iniziare la fase di sincronizzazione. Le classi che si utilizzano derivano dalle classi base definite in questa dll. La versione di tale dll è 3.5, allineata appunto con SQL CE 3.5 che, come abbiamo accennato, viene utilizzato per lo store lato client.  &lt;p&gt;· Microsoft.Synchronization.Data.dll: è in versione 1.0 e rappresenta la parte client del meccanismo di sincronizzazione dei dati. Ogni tabella da sincronizzare espone, sempre tramite derivazione da una classe base definita in questa dll, il tipo di replica da effettuare (ad esempio la tabella è in solo download piuttosto che in upload/download incrementale).  &lt;p&gt;· Microsoft.Synchronization.Data.Server.dll: sempre in versione 1.0 rappresenta la parte server che viene invocata dalla parte client durante ogni processo di sincronizzazione dei dati: anche in questo caso lo sviluppatore deve creare classi derivate da classi base esposte da questa dll per definire i comandi da lanciare sul database server per recuperare i dati o aggiornare le modifiche effettuate dal client.  &lt;p&gt;In pratica, lo sviluppatore deve quindi aderire a questo modello architetturale, creando semplicemente delle classi derivate che rappresentano le tabelle da replicare e i comandi da lanciare sul database. Tutte le dll fanno parte del Framework .NET versione 3.5 e quindi non richiedono installazioni separate. Questa tecnologia non è utilizzabile con il .NET Compact Framework e quindi esclude di fatto l’utilizzo su device basati su Windows CE (e ovviamente Windows Mobile visto che il sistema operativo è sempre Windows CE).  &lt;p&gt;Per facilitare questo compito allo sviluppatore Visual Studio 2008 espone un nuovo item da inserire in progetti desktop per automatizzare la crezione di queste classi: il nuovo item prende il nome di Local Database Cache ed è utilizzabile in qualunque progetto desktop.  &lt;p&gt;Procediamo con il wizard di Visual Studio 2008 per capire le tipologie di replica possibili, gli impatti sul server e il codice generato lato client.  &lt;p&gt;Aggiungiamo un nuovo item al progetto:  &lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/ADO.NETSynchronizationservices_9BFF/clip_image004.jpg"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="373" alt="clip_image004" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/ADO.NETSynchronizationservices_9BFF/clip_image004_thumb.jpg" width="575" border="0" /&gt;&lt;/a&gt;  &lt;p&gt;Una volta aggiunto il file .sync è possibile aprirlo con un nuovo editor che facilita la configurazione e la creazione delle classi derivate che abbiamo accennato. La prima parte del designer consente di specificare la stringa di connessione verso il database server e verso il database client SQLCE.  &lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/ADO.NETSynchronizationservices_9BFF/clip_image006.gif"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="335" alt="clip_image006" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/ADO.NETSynchronizationservices_9BFF/clip_image006_thumb.gif" width="482" border="0" /&gt;&lt;/a&gt;  &lt;p&gt;Una volta scelte le connessioni viene creato, se non esistente, il file .SDF di SQLCE all’interno del progetto. Nella parte advanced è possibile scegliere in quali progetti della solution corrente dovranno essere create le classi per la sincronizzazione e se tutte le tabella devono essere sincronizzate in un unica transazione. Queste impostazioni si riflettono sulle proprietà delle classi che Visual Studio crea nei progetti indicati: sono quindi impostazioni modificabili in seguito riaprendo il file .sync oppure modificandoli da codice.  &lt;p&gt;Per ogni tabella (nel nostro caso abbiamo solo la tabella tabFeedback) occorre indicareil tipo di sincronizzazione e se presenti i campi che consentono di individuare le modifiche da scaricare sul client ad ogni replica. Il tutto si effettua semplicemente scegliendo la tabella dal designer:  &lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/ADO.NETSynchronizationservices_9BFF/clip_image008.jpg"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="443" alt="clip_image008" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/ADO.NETSynchronizationservices_9BFF/clip_image008_thumb.jpg" width="570" border="0" /&gt;&lt;/a&gt;  &lt;p&gt;La prima operazione da eseguire è scegliere la modalità di replica: nella sezione client configuration si puà scegliere se creare una nuova tabella o utilizzare una tabella esistente nel database SQLCE per accogliere i dati che arrivano dal server. Nella prima combo-box invece si indica il tipo di replica da effettuare. Le opzioni sono le seguenti  &lt;p&gt;· Snapshot: ogni operazioni di sincronizzazione sulla tabella scarica l’intero set dei dati  &lt;p&gt;· Download-only: la tabella viene solamente sincronizzata dal server verso il client; vengono scaricate solo le modifiche effettuate dall’utlima sincronizzazione  &lt;p&gt;· Upload-only: la tabella viene solamente sincronizzata dal client verso il server; vengono inviate solo le modifiche effettuate dall’utlima sincronizzazione  &lt;p&gt;· Bidirectional: viene effettuato prima l’upload incrementale e poi il download delle modifiche server.  &lt;p&gt;Nella sezione Server Configuration è fondamentale indicare i campi della tabella sul database server da utilizzare per individuare gli insert e le modifiche: le query generate infatti si basano su una clausola WHERE per individuare solo gli aggiornamenti effettuati dopo l’ultima sincronizzazione da parte del client: le ancore agli ultimi valori sono supportati nativamente da SQL CE fin dalla versione 1.0 come vedremo più avanti.  &lt;p&gt;Sempre nella sezione Server Configuration è importante indicare la tabella in cui verranno accolte le cancellazioni effettuate server side e il campo da utilizzare per individuare queste eliminazioni di record.  &lt;p&gt;Dopo aver premuto OK il database server si presenta così:  &lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/ADO.NETSynchronizationservices_9BFF/clip_image010.jpg"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="570" alt="clip_image010" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/ADO.NETSynchronizationservices_9BFF/clip_image010_thumb.jpg" width="358" border="0" /&gt;&lt;/a&gt;  &lt;p&gt;Nella tabella tabFeedbacks sono stati aggiunti due campi LastEditDate e CreationDate (indicati nel designer nella sezione Server Configuration) per memorizzare la data di modifica e di creazione dei recordo: tali campi vengono valorizzati dai due trigger omonimi come si può vedere dalla figura sopra. Viene creata, sempre secondo i valori indicati nel designer, la tabella _Tombstone, alimentata anch’essa dal trigger DeletionTrigger a fronte di ogni cancellazione effettuata.  &lt;p&gt;Sui campi citati vengono montati degli indici per rendere efficiente la ricerca delle modifiche effettuate quando viene avviata la fase di sincronizzazione.  &lt;p&gt;Il database lato client, creato e sincronizzato subito al termine del wizard, si presenta così:  &lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/ADO.NETSynchronizationservices_9BFF/clip_image012.jpg"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="446" alt="clip_image012" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/ADO.NETSynchronizationservices_9BFF/clip_image012_thumb.jpg" width="491" border="0" /&gt;&lt;/a&gt;  &lt;p&gt;Oltre ai campi sincronizzati troviamo alcuni campi di sistema (iniziano con un doppio “_”) che consentono al motore di SQLCE di tenere traccia delle modifiche lato client. Da sempre l’engine di SQLCE utilizza campi di sistema per tenere traccia delle modifiche nativamente, visto che su SQL CE non è possibile creare dei trigger: non occorre in ogni caso modificare da codice tali valori.  &lt;p&gt;Su l database SQLCE vengono create anche alcune tabelle:  &lt;p&gt;· __sysOCSDeletedRows  &lt;p&gt;· __sysOCSTrackedObjects  &lt;p&gt;· __sysSyncArticles  &lt;p&gt;· __sysTxCommitSequence  &lt;p&gt;La prima tabella tiene le righe cancellate lato client, la seconda contiene l’elenco degli oggetti da tenere sotto controllo durante le normali operazioni sul DB, la terza tabella, ben conosciuta a chi ha usato la merge replication, tiene l’elenco delle tabella sotto replica, mentre l’ultima tiene traccia della sequenza delle operazioni transazionali andate a buon fine: sono tutte tabelle di sistema non visibili dall’interfaccia di amministrazione di SQL CE (per elencare le tabelle di sistema si può utilizzare select * from information_schema.tables, mentre per vederne il contenuto è sufficiente una semplice select).  &lt;p&gt;Per effettuare una sincronizzazione è sufficiente utilizzare il codice seguente:  &lt;p&gt;LocalDataCacheDevCon2006_FeedbackSyncAgent syncAgent = new LocalDataCacheDevCon2006_FeedbackSyncAgent();  &lt;p&gt;Microsoft.Synchronization.Data.SyncStatistics syncStats = syncAgent.Synchronize();  &lt;p&gt;La prima riga di codice crea l’oggetto syncAgent (la classe è stata generata in automatico dal designer di Visual Studio) e la seconda riga invoca il metodo Synchronize. Tale metodo restituisce un oggetto di tipo SyncStatistics da cui è possibile capire il numero delle modifiche inviate, il numero delle modifiche ricevute per ogni tabella sincronizzata.  &lt;p&gt;E’ possibile modificare, come accennato all’inizio dell’articolo, il comportamento di replica agendo sulle proprietà della classe derivata da SyncAgent. Ad esempio prima di lanciare la replica è possibile impostare la direzione della replica anche da codice:  &lt;p&gt;LocalDataCacheDevCon2006_FeedbackSyncAgent syncAgent = new LocalDataCacheDevCon2006_FeedbackSyncAgent();  &lt;p&gt;// Decido la direzione  &lt;p&gt;syncAgent.tabFeedbacks.SyncDirection = &lt;br /&gt;Microsoft.Synchronization.Data.SyncDirection.Snapshot;&lt;br /&gt;Microsoft.Synchronization.Data.SyncStatistics syncStats = syncAgent.Synchronize();  &lt;p&gt;In questo caso, a prescindere dai parametri indicati nel designer di Visual Studio, stiamo forzando una sincronizzazione di tipo SnatpShot ovvero la ricrezione della tabella lato client e lo scarico di tutti i dati della tabella server.  &lt;p&gt;Come abbiamo indicato precedentemente, Visual Studio 2008, crea anche le classi SyncAdapter server side; il compito di tali classi è specificare i comandi da lanciare sul DB per gestire gli inserimenti, le modifiche e il recupero (incrementale o meno) delle righe modificate. Ecco l’estratto della classe SyncAdapter relativo alla nostra tabella tabFeedbacks:  &lt;p&gt;public partial class tabFeedbacksSyncAdapter : Microsoft.Synchronization.Data.Server.SyncAdapter {&lt;br /&gt;private void InitializeCommands() &lt;br /&gt;{  &lt;p&gt;// tabFeedbacksSyncTableInsertCommand command.  &lt;p&gt;this.InsertCommand = new System.Data.SqlClient.SqlCommand();  &lt;p&gt;this.InsertCommand.CommandText = @&amp;quot; SET IDENTITY_INSERT &lt;br /&gt;dbo.tabFeedbacks ON INSERT INTO dbo.tabFeedbacks ([idFeedback], [FeedbackGUID], [FeedbackTechnology], [FeedbackLevel], [FeedbackSlot], [FeedbackComment], [LastEditDate], [CreationDate]) VALUES (@idFeedback, @FeedbackGUID, @FeedbackTechnology, @FeedbackLevel, @FeedbackSlot, @FeedbackComment, @LastEditDate, @CreationDate” ;&lt;br /&gt;// tabFeedbacksSyncTableDeleteCommand command.  &lt;p&gt;this.DeleteCommand = new System.Data.SqlClient.SqlCommand();  &lt;p&gt;this.DeleteCommand.CommandText = &amp;quot;DELETE FROM dbo.tabFeedbacks WHERE ([idFeedback] = @idFeedback) SET @sync_row_cou&amp;quot; +  &lt;p&gt;&amp;quot;nt = @@rowcount&amp;quot;;  &lt;p&gt;// tabFeedbacksSyncTableUpdateCommand command.  &lt;p&gt;this.UpdateCommand = new System.Data.SqlClient.SqlCommand();  &lt;p&gt;this.UpdateCommand.CommandText = @&amp;quot;UPDATE dbo.tabFeedbacks SET [FeedbackGUID] = @FeedbackGUID, [FeedbackTechnology] = @FeedbackTechnology, [FeedbackLevel] = @FeedbackLevel, [FeedbackSlot] = @FeedbackSlot, [FeedbackComment] = @FeedbackComment, [LastEditDate] = @LastEditDate, [CreationDate] = @CreationDate WHERE ([idFeedback] = @idFeedback) SET @sync_row_count = @@rowcount&amp;quot;;  &lt;p&gt;// selectIncrementalInsertsCommand command.  &lt;p&gt;this.SelectIncrementalInsertsCommand = new System.Data.SqlClient.SqlCommand();  &lt;p&gt;this.SelectIncrementalInsertsCommand.CommandText = &amp;quot;SELECT * FROM [tabFeedbacks]&amp;quot;;  &lt;p&gt;this.SelectIncrementalInsertsCommand.CommandType = System.Data.CommandType.Text;  &lt;p&gt;// tabFeedbacksSyncTableSelectConflictDeletedRowsCommand command.  &lt;p&gt;this.SelectConflictDeletedRowsCommand = new System.Data.SqlClient.SqlCommand();  &lt;p&gt;this.SelectConflictDeletedRowsCommand.CommandText = &amp;quot;SELECT [idFeedback], [DeletionDate] FROM [tabFeedbacks_Tombstone] WHERE ([idFeedback] = @idFeedback)&amp;quot;;  &lt;p&gt;// tabFeedbacksSyncTableSelectConflictUpdatedRowsCommand command.  &lt;p&gt;this.SelectConflictUpdatedRowsCommand = new System.Data.SqlClient.SqlCommand();  &lt;p&gt;this.SelectConflictUpdatedRowsCommand.CommandText = &amp;quot;SELECT [idFeedback], [FeedbackGUID], [FeedbackTechnology], [FeedbackLevel], [FeedbackSlot], [FeedbackComment], [LastEditDate], [CreationDate] FROM dbo.tabFeedbac&amp;quot; +  &lt;p&gt;&amp;quot;ks WHERE ([idFeedback] = @idFeedback)&amp;quot;;  &lt;p&gt;// tabFeedbacksSyncTableSelectIncrementalInsertsCommand command.  &lt;p&gt;this.SelectIncrementalInsertsCommand = new System.Data.SqlClient.SqlCommand();  &lt;p&gt;this.SelectIncrementalInsertsCommand.CommandText = @&amp;quot;SELECT [idFeedback], [FeedbackGUID], [FeedbackTechnology], [FeedbackLevel], [FeedbackSlot], [FeedbackComment], [LastEditDate], [CreationDate] FROM dbo.tabFeedbacks WHERE ([CreationDate] &amp;gt; @sync_last_received_anchor AND [CreationDate] &amp;lt;= @sync_new_received_anchor)&amp;quot;;  &lt;p&gt;// tabFeedbacksSyncTableSelectIncrementalDeletesCommand command.  &lt;p&gt;this.SelectIncrementalDeletesCommand = new System.Data.SqlClient.SqlCommand();  &lt;p&gt;this.SelectIncrementalDeletesCommand.CommandText = &amp;quot;SELECT [idFeedback], [DeletionDate] FROM [tabFeedbacks_Tombstone] WHERE (@sync_initialized = 1 AND [DeletionDate] &amp;gt; @sync_last_received_anchor AND [DeletionDate]&amp;quot; +  &lt;p&gt;&amp;quot; &amp;lt;= @sync_new_received_anchor)&amp;quot;;  &lt;p&gt;// tabFeedbacksSyncTableSelectIncrementalUpdatesCommand command.  &lt;p&gt;this.SelectIncrementalUpdatesCommand = new System.Data.SqlClient.SqlCommand();  &lt;p&gt;this.SelectIncrementalUpdatesCommand.CommandText = @&amp;quot;SELECT [idFeedback], [FeedbackGUID], [FeedbackTechnology], [FeedbackLevel], [FeedbackSlot], [FeedbackComment], [LastEditDate], [CreationDate] FROM dbo.tabFeedbacks WHERE ([LastEditDate] &amp;gt; @sync_last_received_anchor AND [LastEditDate] &amp;lt;= @sync_new_received_anchor AND [CreationDate] &amp;lt;= @sync_last_received_anchor)&amp;quot;;  &lt;p&gt;}  &lt;p&gt;}  &lt;p&gt;Formattazione complicata per un articolo a parte, i nomi dei comandi sono chiari e non necessita di spiegazione: vengono creati i comandi per esegure le INSERT, gli UPDATE, i DELETE rispetto alle modifiche inviate dai client e i tre comandi per rintracciare, a fronte di una operazioni di sincronizzazione, le modifiche effettuate sul server da inviare al client in modo incrementale.  &lt;p&gt;In base al tipo di sincronizzazione scelto nel designer di Visual Studio vengono generati solo i comandi necessari: ad esempio, se la sincronizzazione è di tipo upload-only non vengono generati i comandi per rintracciare le modifiche effettuate al server, così come se la sincronizzazione è di tipo download-only non vengono generati i comandi per applicare le modifiche al server.  &lt;p&gt;Vista la natura dei comandi generati (non sono stored procedure, le modifiche vengono rintracciate per data di modifica, i dati non vengono partizionati a priori) ADO.NET Sync Service non si adatta a scenari con centinaia di migliaia di record oppure a scenari in cui le modifiche vengono partizionate per zone o per client (territorialità dei dati) che vengono invece brillantemente risolte da tecnologie più corpose e complete come la Merge Replication. Il messaggio che mi preme far passare è che ADO.NET Sync Service è il primo passo di una lunga strada e quindi si adatta benissimo a scenari semplici in cui lo sviluppatore vuole avere il controllo completo e dove non è possibile utilizzare la Merge Replication. Per scenari più “corposi” in cui occorre partizionare molte tabelle con molti record in base al client occorrono tecniche più efficienti di utilizzo dei dati (non si può lanciare una query su 100.000 record per estrarre solo le modifiche destinate ad un agente di vendita ma occorre partizionarle a priori, gestendo anche l’eventuale, ma frequente cambio di territorialità dei dati), tecniche che la Merge Replication espone in modo completo.  &lt;p&gt;Per questo primo articolo introduttivo è tutto, ci risentiamo presto con un articolo di approfondimento sulle classe generate e sulle tecniche per raggruppare i dati, gestire dati per singolo client e passare parametri al motore di replica.  &lt;p&gt;Roberto Brunetti&lt;br /&gt;MCP, MCSD.NET, MCSE + I, MCT&lt;br /&gt;&lt;a href="mailto:roberto@devleap.it"&gt;roberto@devleap.it&lt;/a&gt;&lt;br /&gt;&lt;a href="http://blogs.devleap.com/rob"&gt;http://blogs.devleap.com/rob&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.thinkmobile.it"&gt;www.thinkmobile.it&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.devleap.com/aggbug.aspx?PostID=18435" width="1" height="1"&gt;</content><author><name>rob</name><uri>http://blogs.devleap.com/members/rob.aspx</uri></author></entry><entry><title>VISUAL STUDIO 2008, .NET FW e CF 3.5</title><link rel="alternate" type="text/html" href="http://blogs.devleap.com/articolidevleap/archive/2007/11/17/visual-studio-2008-net-fw-amp-cf-3-5.aspx" /><id>http://blogs.devleap.com/articolidevleap/archive/2007/11/17/visual-studio-2008-net-fw-amp-cf-3-5.aspx</id><published>2007-11-17T00.36.00Z</published><updated>2007-11-17T00.36.00Z</updated><content type="html">&lt;p&gt;Articoli pubblicati su week.it che ho riuniuto in un unico post. &lt;/p&gt;
&lt;p&gt;Uscita la Beta 2 di .NET 3.5 e Visual Studio 2008 (ormai siamo alla RTM, ma era bello lasciare questa frase di inizio agosto che ci ricorda il caldo e le ferie J è giunto il momento di iniziare una serie di articoli settimanali per analizzarne le novità indicando, ove possibile, i puntatori verso informazioni più corpose. 
&lt;p&gt;Per prima cosa occorre separare nettamente cosa offre la nuova versione del Framework .NET e quali strumenti mette a disposizione Visual Studio 2008 a supporto delle nuove feature, senza dimenticare i nuovi strumenti indipendenti dalla versione del Framework. Con questa frase voglio sottolineare, se ce ne fosse ancora bisogno, che la piattorma .NET offre, da sempre, librerie e componenti utilizzabili senza l’ausilio di Visual Studio. Dall’altra parte, Visual Studio, in base all’edizione scelta, fornisce non solo strumenti che automatizzano e facilitano l’utilizzano di alcune di queste librerie e componenti, ma fornisce strumenti di supporto per la gestione del ciclo di vita di un software, per l’analisi del codice sorgente e del codice in esecuzione, per la definizione visuale di classi, diagrammi applicativi e di deployment e non ultimo strumenti per la gestione di test sul codice. Quindi se da una parte potremmo scrivere applicazioni, anche complesse, senza utilizzare Visual Studio, dall’altra parte, lo strumento è diventato un alleato importante e indispensabile per la gestione dei progetti software. 
&lt;p&gt;Nei vari articoli che seguono, nelle varie settimane, analizzeremo separatamente, le novità che riguardano la piattaforma, come l’integrazione di AJAX nel motore ASP.NET, i nuovi costrutti C# e VB, l’introduzione di LINQ per citarne alcuni, e le novità che riguardano l’ambiente di sviluppo, non tanto rispetto alle novità del Framework, quanto rispetto agli strumenti di supporto della soluzione software, come Unit Testing, nuove funzionalità di refactoring, nuovi designer che appunto prescindono dalla versione del Frameowrk utilizzato: ad esempio, le nuove funzionalità di refactoring possono lavorare anche su progetti .NET FW 2.0/3.0. 
&lt;p&gt;Chiudiamo questo primo articolo della serie con un chiarimento sulle versioni con cui lavoreremo: ad oggi, come saprete, i compilatori .NET sono in versione 2.0, versione indicata anche per i linguaggi (C# è in versione 2.0, VB.NET è in versione 8, ovvero la seconda versione di VB.NET dopo la 6.0 che allineata al vecchio mondo COM); il .NET Compact Framework è in versione 2.0 (SQLCE è in versione 3.1), mentre il Framework completo è in versione 3.0: la versione 3.0 ha portato novità con l’aggiunta delle librerie WCF, WPF, WF che si utilizzano ancora con C# 2.0 (e VB.NET 8) e, appunto, i compilatori in versione 2.0. 
&lt;p&gt;La versione 3.5 “complica ancora un po’” lo scenario: i compilatori fanno un salto di versione passando alla 3 (quindi avremo C# 3.0 e VB.NET 9), il runtime passa alla versione 3.5 inglobando anche molte librerie ad oggi disponibili come download separato. Il Framework è quindi in versione 3.5 così come il Compact Framework passa alla versione 3.5 e si porta dietro SQL Compact Edition versione 3.5. Visual Studio è invece in versione 2008 e consente la creazione di progetti che si basano sul runtime del Framework 2.0, 3.0 (in pratica versione 2.0 più WPF, WCF, WF) e versione 3.5. Sviluppando un progetto versione 3.5 si ottengono le reference (o si devono fare a mano le reference J) verso le librerie 2.0 per quanto riguarda le funzionalitá base (ad esempio la System.Transaction), verso le librerie 3.0 per quanto riguarda le classi aggiunte nella versione 3.0 (WPF, WCF, WF, WCS) e/o verso le librerie versione 3.5 per le novitá introdotte: queste ultime sono nuove librerie, come il caso di LINQ, rivitazioni di librerie esistenti, come nel caso della System.Web.Extension, oppure aggiunte a funzionalitá della 3.0, come ad esempio i servizi di hosting di workflow in WCF (WorkflowServiceHost). 
&lt;p&gt;&lt;b&gt;Mobile Development&lt;/b&gt; 
&lt;p&gt;La nuova versione di Visual Studio viene equipaggiata con template e SDK per le piattaforme Pocket PC 2003, Windows CE, Windows Mobile 5.0 Pocket PC e Windows Mobile 5.0 SmartPhone e supporta la creazione/gestione di progetti basati sul .NET Compact Framework 2.0 e 3.5. E’ anche possibile convertire un progetto dalla versione .NET CF 2.0 alla versione 3.5. In pratica scegliendo la versione vengono proposte le reference corrette agli assembly .NET nelle varie versioni e agganciato il compilatore allineato alla versione del linguaggio utilizzato. Come abbiamo accennato nel primo articolo della serie, verrà utilizzato il compilatore C# versione 3.0 per progetti .NET CF 3.5 e l’attuale compilatore C# 2.0 per progetti in versione 2.0. 
&lt;p&gt;Gli emulatori utilizzano il Device Emulator 2.0 (disponibile oggi al download e installabile anche con Visual Studio 2005), mentre il Device Emulator 3.0 è installabile, almeno per adesso, come download separato. La nuova piattaforma di emulazione fornisce il Device Configuration Manager che elimina la necessità attuale di comporre manualmente file xml per modificare la configurazione degli emulatori. Risulta quindi molto semplice modificare le impostazioni di security per aderire a quelle dei device in commercio: con semplici selezioni da una interfaccia grafica si può lavorare One-Tier, Two-Tier, Locked o Prompt. 
&lt;p&gt;Una delle novità più interessanti è sicuramente la possibilità (offerta anche dalla versione Professional) di creare Unit Test su codice .NET CF e eseguirli su device o emulatore. La funzionalità è molto simile a quanto oggi troviamo in Visual Studio Team System for Tester: in pratica sono state aggiunte le librerie mobile per eseguire i test e collezionarne i risultati da riportare nell’IDE di Visual Studio. I risultati possono poi essere pubblicati, associandoli ad una Build, in Team Foundation Server. 
&lt;p&gt;&lt;b&gt;Upgrade&lt;/b&gt; 
&lt;p&gt;Quando si apre un progetto/solution VS 2005 in VS 2008 vengono aggiornati i file di progetto e della solution al nuovo formato. 
&lt;p&gt;Occorre tenere presente che: 
&lt;ul&gt;
&lt;li&gt;Un progetto .NET CF 1.0 viene aggiornato (come reference) alla versione 2.0 del .NET CF 
&lt;li&gt;Un progetto .NET CF 2.0 rimane invariato, &lt;b&gt;non &lt;/b&gt;viene quindi portato alla versione 3.5 del runtime 
&lt;li&gt;I riferimenti a SQLCE&amp;nbsp;3.0 (SQL 2005 Mobile Edition) e SQLCE 3.1 vengono aggiornati a SQL CE 3.5 
&lt;li&gt;I progetti SmartPhone 2003 vengono aggiornati a Windows Mobile 5.0 for SmartPhone &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Dopo la conversione, su ogni progetto, con tasto dx, è possibile aggiornare le librerie&amp;nbsp;al .NET CF 3.5.&amp;nbsp; 
&lt;p&gt;E&amp;#39; poi possibile, come in VS 2005, modificare la &amp;quot;Target Platform&amp;quot; per portare i progetti da una piattaforma all&amp;#39;altra. 
&lt;p&gt;Per quanto riguarda SQL CE, oltre all&amp;#39;ormai famoso upgrade.exe che consente sul device di aggiornare il database .sdf alle nuove versioni (era presente anche in SQLCE 3.0 e SQLCE 3.1), è possibile convertire i database direttamente da VS 2008. E&amp;#39; sufficiente aprire il file sdf dal progetto (o da dove volete ovviamente) per poter effettuare l&amp;#39;upgrade al volo. 
&lt;p&gt;Piú avanti vedremo le novità del .NET CF 3.5 come LINQ e WCF e gli strumenti del .NET CF 3.5 SDK per eseguire profiling e analisi delle performance di una applicazione. Come abbiamo avuto modo di chiarire nel precedente articolo, questi strumenti sono indipendenti da Visual Studio. 
&lt;p&gt;&lt;b&gt;Visual Studio 2008 for Mobile Dev&lt;/b&gt; 
&lt;p&gt;Il .NET CF 3.5 adesso installa le stringhe di risorse sul device/emulatore tramite un nuovo cab denominato NETCFv35.Messages.EN.CAB che si trova sotto x:\program files\Microsoft.NET\SDK\CompactFramework\v3.5\windowsce\Diagnostics. 
&lt;p&gt;La creazione di un nuovo progetto presenta una nuova maschera, simile a quanto avveniva in VS 2003: non si sceglie il progetto dall&amp;#39;alberino delle varie solution disponibili, ma è sufficiente scegliere Smart Device: una volta scelto il tipo di progetto in una seconda maschera si sceglie la tipologia di piattaforma e poi la versione del .NET CF da utilizzare per le reference e per la distribuzione del runtime sul device. Si può optare per .NET CF 2.0 o per .NET CF 3.5. 
&lt;p&gt;N.B. le immagini incluse sono ridotte come dimensione: accanto ad ognuna il link verso la dimensione reale. 
&lt;p&gt;Questa la prima maschera: 
&lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6138/original.aspx"&gt;&lt;img height="323" alt="http://thinkmobile.it/photos/orcas/images/6138/425x323.aspx" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VISUALSTUDIO2008.netfwcf3.5_1684/clip_image001.jpg" width="424" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;Come si nota le piattaforme per cui è installato nativamente l&amp;#39;SDK sono Pocket PC 2003, Windows CE, Windows Mobile 5.0 for Pocket PC e SmartPhone. 
&lt;p&gt;Una volta scelta la piattaforma si sceglie la versione del .NET CF da utilizzare: 
&lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6139/original.aspx"&gt;&lt;img height="323" alt="http://thinkmobile.it/photos/orcas/images/6139/425x323.aspx" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VISUALSTUDIO2008.netfwcf3.5_1684/clip_image002.jpg" width="424" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;&amp;nbsp;Dopo la scelta della versione del .NET CF, come sempre scegliere Device Application, Class Library e così via per creare il tipo di progetto. 
&lt;p&gt;Il designer delle Windows Form (visto che WPF non è disponibile sul .NET CF 3.5) si presenta molto simile al precedente: si può scegliere il form factor da assegnare ad ogni form e ruotare lo schermo del designer come nella versione 2005 di VS. 
&lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6140/original.aspx"&gt;&lt;img height="309" alt="http://thinkmobile.it/photos/orcas/images/6140/425x309.aspx" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VISUALSTUDIO2008.netfwcf3.5_1684/clip_image003.jpg" width="425" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;Anche la toolbox si presenta più o meno identica. Questo l&amp;#39;elenco dei controlli: 
&lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6141/original.aspx"&gt;&lt;img height="425" alt="http://thinkmobile.it/photos/orcas/images/6141/81x425.aspx" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VISUALSTUDIO2008.netfwcf3.5_1684/clip_image004.jpg" width="81" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;La configurazione dell&amp;#39;emulatore da Visual Studio prevede quanto conosciamo con l&amp;#39;attuale Device Emulator 2.0 e consente la gestione del livello della batteria: questa funzione risulta molto comoda per testare un&amp;#39;applicativo power-aware (come dovrebbero essere tutti): è inutile lanciare una operazione lunga di analisi sui dati, ad esempio, se resta il 2% di batteria. 
&lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6142/original.aspx"&gt;&lt;img height="328" alt="http://thinkmobile.it/photos/orcas/images/6142/425x328.aspx" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VISUALSTUDIO2008.netfwcf3.5_1684/clip_image005.jpg" width="425" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;Molto interessante il nuovo Device Configuration Manager, primo fra gli strumenti per facilitare la configurazione di device e emulatori: ad oggi è necessario comporre i file .xml di provisioning e &amp;quot;installarli&amp;quot; tramite rapiconfig.exe. Con questo nuovo strumento risulta molto semplice leggere la configurazione, modificarla e vedere le differenze fra la configurazione desiderata e quella attuale. Si possono importare anche i nostri file di provisioning esistenti per una facile migrazione al nuovo strumento. 
&lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6144/original.aspx"&gt;&lt;img height="284" alt="http://thinkmobile.it/photos/orcas/images/6144/425x284.aspx" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VISUALSTUDIO2008.netfwcf3.5_1684/clip_image006.jpg" width="425" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;Risulta molto semplice così testare l&amp;#39;applicazione firmata o non firmata sulle varie configurazioni dei device One-Tier, Two-Tier, Locked, Prompt e così via. 
&lt;p&gt;Tramite questo strumento è possibile visualizzare i certificati digitali installati su device e emulatori, installarne di nuovi e verificarne i dettagli. Una nota, i nomi dei certificate store sono cambiati: non abbiamo più il privileged e unprivileged, ma Privileged Store e Standard Store, dove il secondo rappresenta lo store per i certificati con cui le applicazioni possono girare in normal-mode su device two-tier. 
&lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6143/original.aspx"&gt;&lt;img height="285" alt="http://thinkmobile.it/photos/orcas/images/6143/425x285.aspx" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VISUALSTUDIO2008.netfwcf3.5_1684/clip_image007.jpg" width="425" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;Il .NET CF Remote Performance Monitor consente, nella nuova versione di fare un &amp;quot;attach to process&amp;quot; rendendo più semplice l&amp;#39;analisi di una porzioni di applicazione: la versione attuale deve lanciare l&amp;#39;applicazione e quindi ci costringe a visualizzare i dati complessivi di tutta l&amp;#39;applicazione fino a raggiungere il punto in cui si desidera effettuare le verifiche. La parte device-side viene installata in automatico dallo strumento senza bisogno di copiare manualmente i file nella directory \Windows: qualche problemino sulla mia Beta non consente di eseguire questa operazione in automatico e quindi ho dovuto comunque copiare i file a mano. I nuovi file device-side hanno nomi diversi dai precedenti e più precisamente sono: rtf3_5.dll e rtfhost3_5.exe. Tali file si trovano sempre nella directory dell&amp;#39;SDK del .NET CF 3.5 x:\program files\Microsoft.NET\SDK\CompactFramework\v3.5: ricordatevi di scegliere poi la directory corretta in base al processore del device; per gli emulatori si utilizza sempre la versione ARM. 
&lt;p&gt;Nella prossima immagine la directory con gli strumenti lato PC di sviluppo. Oltre al .NET CF RPM, troviamo LogViewer, già presente nella versione 2.0 SP1/SP2 e due nuovi strumenti: 
&lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6146/original.aspx"&gt;&lt;img height="319" alt="http://thinkmobile.it/photos/orcas/images/6146/425x319.aspx" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VISUALSTUDIO2008.netfwcf3.5_1684/clip_image008.jpg" width="425" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;Il primo NETCFCLRProfiler è una versione ridotta (e per la verità anche diversa) del Profiler del Framework completo. Consente di analizzare nel dettaglio un&amp;#39;applicazione in esecuzione: anche in questo caso ci si può &amp;quot;attaccare&amp;quot; ad un processo già avviato e l&amp;#39;installazione delle dll lato device è automatica (come sempre sono sfigato e ho dovuto copiare a mano clrpro3_5.dll sul device). Lo strumento visualizza anche sotto forma di flusso grafico le chiamate fra i vari metodi consentendo una semplice (si fa per dire quando si parla di profiling in generale) individuazione dei punti della call stack che possono dare problemi. 
&lt;p&gt;Come abbiamo accennato, il compact frameowrk 3.5 arriva con qualche dll in più per supportare LINQ e WCF (sempre in versione ridotta: entrambi sono c.a. 250KB come obiettivo nella versione finale) e i nomi dei cab sono stati leggermente rivisti. 
&lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6147/original.aspx"&gt;&lt;img height="229" alt="http://thinkmobile.it/photos/orcas/images/6147/425x229.aspx" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VISUALSTUDIO2008.netfwcf3.5_1684/clip_image009.jpg" width="425" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;&amp;nbsp;Nella System.ServiceModel si trovano le &amp;quot;porzioni&amp;quot; del motore di WCF e il binding basicHttpBinding, mentre in Microroft.ServiceModel.Channels.Mail.* il nuovo canale (non disponibile in WCF su desktop) WindowsMobileMailBinding che consente lo scambio di messaggi SOA sfruttando il canale della posta elettronica fra device (Pocket Outlook) e&amp;nbsp; Exchange 2007; ricordo che Exchange 2007 supporta il push dei messaggi verso il device. 
&lt;p&gt;Come sempre le sottodirectory wce400 e wce500 contengono i cab per l&amp;#39;installazione reale su device o emulatore in base alla versione del sistema operativo. Ricordo che Windows Mobile 6.0 si basa sempre su Windows CE 5, per precisione sulla 5.2. 
&lt;p&gt;System.Data.Entities contiene invece le parti applicative dell&amp;#39;entitiy framework, mentre il provider è contenuto sotto System.Data.SqlServerCe.Entitiy.dll che arriva con l&amp;#39;installazione di Sql Server Compact Edition 3.5. 
&lt;p&gt;SQL CE 3.5 arriva con qualche piccola novità per i device e con grandi novità su utilizzato su desktop, Tablet o UMPC. 
&lt;p&gt;La directory di installazione sul pc di sviluppo è x:\program files\Microsoft SQL server Compact Edition\v3.5 e si presenta così: 
&lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6148/original.aspx"&gt;&lt;img height="228" alt="http://thinkmobile.it/photos/orcas/images/6148/425x228.aspx" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VISUALSTUDIO2008.netfwcf3.5_1684/clip_image010.jpg" width="424" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;Come accennato, entity framework viene reso disponibile tramite System.Data.SqlServerCe.Entity, ma solo se utilizzato su PC, Tablet o UMPC: non è quindi disponibile per Windows Mobile. 
&lt;p&gt;L&amp;#39;installazione prevede diversi componenti: 
&lt;p&gt;1) SSCEVSTools-ENU.msi: installa i componenti design-time in Orcas sotto la classica directory x:\program files\microsoft visual studio 9\Common7\IDE. Questi componenti non devono essere distribuiti 
&lt;p&gt;2) SSCERuntime-ENU.msi: installa i componenti di runtime per desktop, tablet e UMPC. Sono indispensabili sia a runtime che a design time. Questo MSI installa anche i nuovi componenti per la versione desktop di SQCE 3.5: Microsoft Synchronization Services for ADO.NET (OCS) e la già citata System.Data.SqlServerCe.Entity.dll. 
&lt;p&gt;3) SSCEDeviceRuntime.msi: installa i componenti destinati ai device e emulatori sulla macchina. Questi componenti sono necessari per l&amp;#39;integrazione con VS Orcas anche sulla macchina di sviluppo. 
&lt;p&gt;Le novità che abbiamo bollato come minori (rispetto appunto a EntityFramework e OCS) riguardano soprattutto il query processor : 
&lt;p&gt;- data type di tipo timestamp 
&lt;p&gt;- nested query 
&lt;p&gt;- CROSS apply e OUTER APPLY 
&lt;p&gt;- CAST 
&lt;p&gt;- TOP (finalmente !!!!!) diventa così più semplice paginare i dati per la loro visualizzazione nei minuscoli schermi 
&lt;p&gt;Oltre a OCS e Entity Framework, SQL CE 3.5, se utilizzato sul desktop, fornisce la possibilità di rientrare in una transazione creata con la System.Transaction 2.0: in due parole una operazione su SQL CE 3.5 può essere inserita all&amp;#39;interno del TransactionScope. 
&lt;p&gt;I Book On Line non sono ancora disponibili. 
&lt;p&gt;Abbiamo accennato nei post precedenti come in Visual Studio Orcas sia possibile effettura Unit Testing su device (o emulatore): credo che questa funzionalità, affiancata dal nuovo .NET CF RPM e dal profiler, siano le novità più importanti e utili della nuova versione. 
&lt;p&gt;Tra l&amp;#39;latro in Orcas gli strumenti di Unit Testing non sono più all&amp;#39;interno di Team System, ma disponibili nella versione Professional, almeno a quanto ci è dato sapere oggi. 
&lt;p&gt;Ecco le maschere di crezione di uno unit test, praticamente identiche (tranne un settaggio) a quanto oggi disponibile in VSTS: 
&lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6151/original.aspx"&gt;&lt;img height="229" alt="http://thinkmobile.it/photos/orcas/images/6151/425x229.aspx" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VISUALSTUDIO2008.netfwcf3.5_1684/clip_image011.jpg" width="425" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6153/original.aspx"&gt;&lt;img height="285" alt="http://thinkmobile.it/photos/orcas/images/6153/425x285.aspx" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VISUALSTUDIO2008.netfwcf3.5_1684/clip_image012.jpg" width="425" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;Nella seconda immagine, come si può notare, la configurazione degli host prevede il tipo Smart Device con relativa piattaforma e scelta fra device e emulatore. 
&lt;p&gt;Se si crea una performance session su uno Unit Test il codice viene fatto girare sul desktop. 
&lt;p&gt;Anche senza l&amp;#39;automatismo in VS Orcas, oggi è possibile eseguire unit test su codice mobile, creando un progetto desktop con i sorgenti mobile linkati al suo interno e oppure compilazioni condizionali nel caso in cui il codice faccia uso di dispositivi, tipo lettore di codice a barre ad esempio, non disponibili sul desktop. Fra qualche giorno posso postare un mio articolo, scritto per Infomedia, proprio su questo argomento. La demo allegata all&amp;#39;articolo è già disponibile sul mio sito Think Mobile all&amp;#39;indirizzo &lt;a href="http://thinkmobile.it/files/folders/mmdcii/entry5896.aspx"&gt;http://thinkmobile.it/files/folders/mmdcii/entry5896.aspx&lt;/a&gt;. 
&lt;p&gt;Il nuovo Device Emulator 3.0 si presenta così: 
&lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6149/original.aspx"&gt;&lt;img height="425" alt="http://thinkmobile.it/photos/orcas/images/6149/350x425.aspx" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VISUALSTUDIO2008.netfwcf3.5_1684/clip_image013.jpg" width="350" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;A parte la user interface pressochè identica, è possibile salvare la configurazione degli emulatori con Save As e riconfigurare l&amp;#39;emulatore. Il file di configurazione (.defcfg) è anche molto semplice da modificare a mano per cambiare al volo qualcosa senza ricorre alla user interface e soprattutto per poter scambiare la configurazione degli emulatori fra i membri di un team di sviluppo senza doverla ricreare su ogni PC di sviluppo. 
&lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6150/original.aspx"&gt;&lt;img height="189" alt="http://thinkmobile.it/photos/orcas/images/6150/425x189.aspx" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VISUALSTUDIO2008.netfwcf3.5_1684/clip_image014.jpg" width="425" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;&lt;b&gt;.NET Compact Framework 3.5&lt;/b&gt; 
&lt;p&gt;Il nostro filone su Visual Studio 2008 e .NET 3.5 prosegue con questo articolo dedicato alle novità del .NET Compact Framework versione 3.5. Le novità vedono l’introduzione di LINQ To SQLCE, Windows Communication Foundation, alcune API per lavorare con certificati digitali e qualche aggiunta alle classi Windows Forms. Oltre a questo troveremo un rivisto Remote Performance Manager e un nuovo CLR Profiler. 
&lt;p&gt;La versione 3.5 utilizza i compilatori in versione 3 (quindi avremo C# 3.0 e VB.NET 9), quindi molte novitá riguardano il linguaggio stesso e i compilatori. Anche SQLCE fa un salto in avanti presentandosi in versione 3.5. Avremo modo di parlare delle novitá del mini/db in un articolo separato. 
&lt;p&gt;l primo nuovo componente è Windows Communication Foundation: si tratta di un subset ridotto dell&amp;#39;attuale versione per il framework completo pensata per comunicazioni device-to-server, server-to-device e device-to-device (Peer to Peer). 
&lt;p&gt;Il subset di funzionalità prevede il trasporto via Http (BasicHttpBinding), un subset delle funzionalità di WS-Security e WS-Addressing, con la possibilità di estensioni custom, l&amp;#39;encoding basato su Text o algoritmi custom. Quanto non citato non è presente: manca quindi il supporto a Service e Contract Model, manca per adesso anche l&amp;#39;utility svcutil.exe che uscirà sotto forma di Power Toy successivamente. 
&lt;p&gt;E&amp;#39; stato creato un trasporto apposito per sfruttare il canale email per l&amp;#39;invio di messaggi WCF: il tutto è accessibile tramite WindowsMobileMailBinding (non presente nella versione completa sul .NET Framework) e sfrutta i servizi esposti da Exchange 2007 per lo store-and-forward dei messaggi. Tramite Exchange 2007 si sfrutta anche la possibilità di usare Push-Technology per inviare messaggi dal server ai device. 
&lt;p&gt;L’elenco completo delle features disponibili con WCF “mobile” rispetto alla versione Full è il seguente: &lt;/p&gt;
&lt;table class="" cellspacing="4"&gt;

&lt;tr&gt;
&lt;td class=""&gt;
&lt;p align="center"&gt;&lt;strong&gt;Feature&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=""&gt;
&lt;p align="center"&gt;&lt;strong&gt;Desktop WCF&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=""&gt;
&lt;p align="center"&gt;&lt;strong&gt;Compact WCF&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;&lt;strong&gt;Binding:&lt;/strong&gt;&lt;/td&gt;
&lt;td class=""&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class=""&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· BasicHttpBinding&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· CustomBinding&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· WindowsMobileMailBinding&lt;/td&gt;
&lt;td class="" align="middle"&gt;N/A&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· ExchangeWebServiceMailBinding&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si, se si installa NetCF &lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;&lt;strong&gt;Formatter&lt;/strong&gt;:&lt;/td&gt;
&lt;td class="" align="middle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="" align="middle"&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· SoapFormatter&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· BinaryFormatter&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;No&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;&lt;strong&gt;Encoder&lt;/strong&gt;:&lt;/td&gt;
&lt;td class="" align="middle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="" align="middle"&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· TextMessageEncoder&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· BinaryMessageEncodingBindingElement&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;No&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· MTOMEncoder&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;No&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· GzipEncoder&lt;/td&gt;
&lt;td class="" align="middle"&gt;No&lt;/td&gt;
&lt;td class="" align="middle"&gt;No&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;&lt;strong&gt;Transport&lt;/strong&gt;:&lt;/td&gt;
&lt;td class="" align="middle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="" align="middle"&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· HttpTransportBindingElement&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· HttpsTransportBindingElement&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· MailTransportBindingElement&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si, se si installa NetCF &lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· MsmqTransportBindingElement&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;No&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· TcpTransportBindingElement&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;No&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· (other transports)&lt;/td&gt;
&lt;td class="" align="middle"&gt;&amp;nbsp;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;No&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;XmlDictionaryReader/Writer&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si; stub sopra XmlTextReader/Writer&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;DataContractSerializer&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;No; compatibile però con DCS via XmlSerializer&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;Service proxy generation&lt;/td&gt;
&lt;td class="" align="middle"&gt;SvcUtil.exe&lt;/td&gt;
&lt;td class="" align="middle"&gt;NetCFSvcUtil.exe (si trova nei Power Toys, non in VS2008&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· Non-HTTP transports&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;No&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· Custom headers&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;No&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;WS-Addressing&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;WS-Security message level security&lt;/td&gt;
&lt;td class="" align="middle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="" align="middle"&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· X.509&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· Username/password&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;No&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· SecurityAlgorithmSuite.Basic256Rsa15&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· SecurityAlgorithmSuite.Basic256&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;No&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;WS-ReliableMessaging&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;No&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;Patterns&lt;/td&gt;
&lt;td class="" align="middle"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="" align="middle"&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· Service model&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;No&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· Message layer programming&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· Buffered messages&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· Streaming messages&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;No&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;· Endpoint descriptions in .config files&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;No&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;Channel extensibility&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=""&gt;Security channel extensibility&lt;/td&gt;
&lt;td class="" align="middle"&gt;Si&lt;/td&gt;
&lt;td class="" align="middle"&gt;No&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&amp;nbsp; 
&lt;p&gt;Il secondo componente importante è LINQ, anch’esso subset del fratello maggiore: sono presenti LINQ to Object, LINQ to XML, LINQ to Dataset; nella Beta2 è apparso il supporto per LINQ to Entities e LINQ to SQL per adesso senza designer associato in Visual Studio 2008: occorre lavorare con Sql Metal per definire il modello. Per una introduzione su LINQ consiglio il libro Introducing LINQ di Paolo Pialorsi e Marco Russo e la relativa community www.introducinglinq.com. 
&lt;p&gt;La nuova versione si porta dietro nuovi strumenti di diagnostica: uno strumento centralizzato per abilitare/disabilitare le funzionalità di logging, dal finalizer log, al diagnostic log passando per Interop e statistiche. 
&lt;p&gt;Molto interessante il CLR Profiler, versione ridotta della versione del framework completo, che fornisce metodi per tracciare il comportamento delle applicazioni. 
&lt;p&gt;Il .NET Compact Framework Remote Performance Monitor 3.5 consente la visualizzazione della FReachable Queue e analisi più dettagliate sugli eventuali memory leak che, contrariamente a quanto pensano in molti, possono comunque verificarsi in ambiente .NET. 
&lt;p&gt;L’elenco completo degli strumenti della versione 3.5 del .NET Compact Framework é 
&lt;p&gt;.NET CF RPM: migliorato&lt;br /&gt;CLR Profiler: nuovo&lt;br /&gt;Logging Options: nuovo&lt;br /&gt;Finalizer Log: nuovo&lt;br /&gt;Network log: esistente&lt;br /&gt;Native Interop&lt;br /&gt;Loader Log 
&lt;p&gt;Gli strumenti non sono inclusi in Visual Studio 2008, ma arrivano come Power Tools, per adesso scaricabili da &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=c8174c14-a27d-4148-bf01-86c2e0953eab&amp;amp;displaylang=en&amp;amp;tm"&gt;http://www.microsoft.com/downloads/details.aspx?familyid=c8174c14-a27d-4148-bf01-86c2e0953eab&amp;amp;displaylang=en&amp;amp;tm&lt;/a&gt;&amp;nbsp;e in versione September CTP. 
&lt;p&gt;Una volta installato il tutto si puó utilizzare Logging Configuration per abilitare e disabilitare, su device e emulatori, le varie opzioni di logging: 
&lt;ul&gt;
&lt;li&gt;Loader 
&lt;li&gt;Native Interop 
&lt;li&gt;Network 
&lt;li&gt;Error 
&lt;li&gt;Finalizer&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Ogni logger scrive le informazioni in un file di log nella stessa directory dove gira l&amp;#39;applicazione. 
&lt;p&gt;Per effettuare analisi sul traffico di rete, i pacchetti spediti, i byte inviati e ricevuti é possibile usare il Network Logger Viewer che visualizza, in forma &amp;quot;grafica&amp;quot; il file di log relativo. 
&lt;p&gt;Ad esempio questo i log su una chiamata ad un servizio WCF in basicHttpBinding effettuata dall&amp;#39;emulatore. 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/.NETCF3.5PowerToolsNetworkLogger_11A70/NetworkLoggerWCFRequest4.jpg"&gt;&lt;img height="403" alt="http://devlab.devleap.it/RobertoB/Immagini/Posts/.NETCF3.5PowerToolsNetworkLogger_11A70/NetworkLoggerWCFRequest_thumb2.jpg" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VISUALSTUDIO2008.netfwcf3.5_1684/clip_image015.jpg" width="554" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;Nella prima griglia si vedono, in base ai timestamp, i vari record di invio/ricezione pacchetti e abilitando (come da figura) le colonne Bytes Sent e Bytes Received si puó facilmente analizzare quante informazioni sono state inviate. 
&lt;p&gt;Per ogni record, nella finestra sotto troviamo il dettaglio dei byte scambiati e lo stream relativo, mentre nella finestrina a destra si vede la rappresentazione testuale. 
&lt;p&gt;In questo esempio, la chiamata riguarda appunto un servizio WCF che accetta un valore intero e restituisce, come da figura sotto la scadenza di una polizza. 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/.NETCF3.5PowerToolsNetworkLogger_11A70/NetworkLoggerWCFReply4.jpg"&gt;&lt;img height="412" alt="http://devlab.devleap.it/RobertoB/Immagini/Posts/.NETCF3.5PowerToolsNetworkLogger_11A70/NetworkLoggerWCFReply_thumb2.jpg" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VISUALSTUDIO2008.netfwcf3.5_1684/clip_image016.jpg" width="566" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;Questo e gli altri strumenti sono utilizzabili anche con applicazioni .NET CF 2.0, senza bisogno di nessuna ricompilazione 
&lt;p&gt;L&amp;#39;unica cosa che occorre fare è eseguire la &amp;quot;vecchia&amp;quot; (si fa per dire) applicazione 2.0 con il runtime versione 3.5. Per farlo occorre creare un file di configurazione (app.exe.config) che indica appunto di far girare l&amp;#39;applicazione con il 3.5 come segue: 
&lt;p&gt;&amp;lt;configuration&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;startup&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;supportedRuntime version=&amp;quot;v3.5.xxxx&amp;quot;/&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/startup&amp;gt;&lt;br /&gt;&amp;lt;/configuration&amp;gt; 
&lt;p&gt;dove xxxx sta per la build che state usando (Beta1, Beta2 o l&amp;#39;imminente RC). La Beta 2 attuale è 3.5.71210. 
&lt;p&gt;Un modo più semplice per farlo è usare NetCFCfg.exe direttamente dal device: questo softwarino consente di 
&lt;ul&gt;
&lt;li&gt;Listare le versioni del .NET CF installate sul device 
&lt;li&gt;Visualizzare il contenuto della GAC 
&lt;li&gt;Editare la configurazione di default del device in base alle varie versioni installate 
&lt;li&gt;Editare appunto i file di configurazione delle applicazioni &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;L&amp;#39;exe&amp;nbsp;può essere copiato a mano nella directory Windows: come sempre occorre prendere quello corretto in base a piattaforma e processore a partire dalla directory C:\Program Files\Microsoft.NET\SDK\CompactFramework\v3.5\WindowsCE (wce500 o wce400 e sottodirectory relativa al processore) o addirittura ottenere una copia automatica quando si attacca il device o l&amp;#39;emulatore ad ActiveSync e si sincronizza il tutto. 
&lt;p&gt;&lt;b&gt;VSTS non solo Mobile&lt;/b&gt; 
&lt;p&gt;Alcuni screen shot che riguardano lo sviluppo con VSTS 2008 in generale. 
&lt;p&gt;Per prima cosa la parte server (Team Foundation Server) si presenta così 
&lt;p&gt;&lt;img height="480" alt="http://thinkmobile.it/photos/orcas/images/6292/640x480.aspx" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VISUALSTUDIO2008.netfwcf3.5_1684/clip_image017.jpg" width="164" border="0" /&gt; 
&lt;p&gt;Si basa su SharePoint v3 (di cui avremo modo di parlare alla &lt;a href="http://blogs.devleap.com/ControlPanel/Blogs/www.sharepointconference.it"&gt;SharePoint Conference&lt;/a&gt;). Il default web site espone le due classiche directory di reporting server, mentre il sito Team Foundation Server espone i servizi per Build, Services, Version Control,&amp;nbsp;OLAP e Work Item Tracking. 
&lt;p&gt;Le varie applicazioni sono divise in 3 Application Pool che ospitano appunto i servizi TFS, la parte di reportistica e l&amp;#39;amministrazione di SharePoint. 
&lt;p&gt;Dal menù di un progetto è possibile&amp;nbsp;generare&amp;nbsp;le &amp;quot;metriche del codice&amp;quot;&amp;nbsp;&amp;nbsp;(Code Metrics suona molto meglio) di cui abbiamo già accennato qualcosa nell&amp;#39;altro &lt;a href="http://blogs.devleap.com/rob/archive/2007/03/15/visual-studio-orcas-ctp-march-2007.aspx"&gt;mio post&lt;/a&gt; sulla CTP di Marzo. 
&lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6293/original.aspx"&gt;&lt;img height="480" alt="http://thinkmobile.it/photos/orcas/images/6293/640x480.aspx" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VISUALSTUDIO2008.netfwcf3.5_1684/clip_image018.jpg" width="197" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;Per capire meglio questa nuova funzionalità prendiamo ad esempio il seguente codice 
&lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6289/original.aspx"&gt;&lt;img height="470" alt="http://thinkmobile.it/photos/orcas/images/6289/640x480.aspx" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VISUALSTUDIO2008.netfwcf3.5_1684/clip_image019.jpg" width="640" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;Una volta generato il Code Metrics si ottiene questo risultato. 
&lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6290/original.aspx"&gt;&lt;img height="206" alt="http://thinkmobile.it/photos/orcas/images/6290/500x375.aspx" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VISUALSTUDIO2008.netfwcf3.5_1684/clip_image020.jpg" width="500" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;&amp;quot;Code Metrics&amp;quot; consente di capire se il codice di un progetto/solution è complesso da manutenere, il livello di coupling, la profondità gerarchica delle classi e l&amp;#39;ormai famoso indice di Cyclomatic Complexity (già presente nel Code Analysis della versione attuale in forma testuale). 
&lt;p&gt;Altra opzione &amp;quot;carina&amp;quot; è la gestione delle using di un sorgente C#. Dal menù contestuale si possono infatti organizzare le using: 
&lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6294/original.aspx"&gt;&lt;img height="342" alt="http://thinkmobile.it/photos/orcas/images/6294/500x375.aspx" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VISUALSTUDIO2008.netfwcf3.5_1684/clip_image021.jpg" width="500" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;Ultimo screenshot: la versione VSTS&amp;nbsp;for DB Pro 2008 presenta&amp;nbsp;nativamente l&amp;#39;analisi del codice T-SQL tramite FXCop (che in&amp;nbsp;realtà già dalla versione 2005 si chiama Code&amp;nbsp;Analysis): queste le regole disponibili, immagino già note a molti: 
&lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6291/original.aspx"&gt;&lt;img height="270" alt="http://thinkmobile.it/photos/orcas/images/6291/500x375.aspx" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VISUALSTUDIO2008.netfwcf3.5_1684/clip_image022.jpg" width="500" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;&lt;b&gt;&lt;/b&gt;
&lt;p&gt;&lt;b&gt;Power Tools VSTS 2008 Architect&lt;/b&gt; 
&lt;p&gt;Il nostro filone su Visual Studio 2008 e .NET 3.5 prosegue con questo articolo dedicato ad un add-in giá disponibile per Visual Studio 2008 Team System Architect Edition che prendeil nome di Power Tools. 
&lt;p&gt;Il componente nasce da una esigenza fondamentale nella progettazione di applicazioni distribuite basate su vari layer: nella versione 2005 di Visual Studio Team System Architect Edition non era possibile rappresentare nel diagramma AD (Application Diagram) progetti di tipo class library che, come da documentazione, dovevano essere considerati parte del progetto principale: in pratica un progetto Windows Form, oppure ASP.NET, oppure Web Service ospitava nel digramma tutte le dll referenziate. 
&lt;p&gt;Se da una parte, questa rappresentazione logica é corretta, dall’altra non consente di rappresentare tutti gli elementi di una soluzione Visual Studio dal punto di vista fisico. Noi, in DevLeap, avevamo optato per un workaround in modo da rappresentare in AD e DD (Deployment Diagram) i progetti di tipo DLL. Tutte le nostre implemtazioni fanno uso di UI Layer, composto da uno o piú progetti di tipo class library, di un Biz Layer che si appoggia a dei factory per l&amp;#39;accesso ai dati o la chiamata a servizi (Web Service o WCF). Utilizzavamo quindi le application di tipo “Generic Application” per ogni class library presente nella soluzione. 
&lt;p&gt;A tal proposito si vedano i post 
&lt;p&gt;&lt;a href="http://blogs.devleap.com/rob/archive/2005/09/06/5670.aspx"&gt;http://blogs.devleap.com/rob/archive/2005/09/06/5670.aspx&lt;/a&gt;&lt;br /&gt;&lt;a href="http://blogs.devleap.com/rob/archive/2007/04/11/solution-che-accompagner-molte-demo-della-devcon-2007.aspx"&gt;http://blogs.devleap.com/rob/archive/2007/04/11/solution-che-accompagner-molte-demo-della-devcon-2007.aspx&lt;/a&gt; 
&lt;p&gt;In pratica il diagramma relativo alla parte BIZ/DAL evidenzia l&amp;#39;uso di Generic Application per rappresentare i progetti di tipo Class Library. 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2008ArchitectPower_E3EE/2VSTS2008PowerToolsEMADClassLibraryPreGeneric2.jpg"&gt;&lt;img height="385" alt="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2008ArchitectPower_E3EE/2VSTS2008PowerToolsEMADClassLibraryPreGeneric_thumb.jpg" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VISUALSTUDIO2008.netfwcf3.5_1684/clip_image023.jpg" width="488" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;In Visual Studio 2008 Architect Edition, a parte altre interessanti novitá, la situazione é rimasta praticamente invariata, a meno di non installare i Power Tools per la versione Architect. Per adesso sono allineati alla Beta 2 di VSTS 2008. 
&lt;p&gt;Con questo add-in per la versione 2008 é finalmente possibile rappresentare e soprattutto descrivere i progetti di tipo class library, legarli al diagramma SDM e come sempre, sincronizzarne le impostazioni con il progetto reale. Ogni connessione fra applicazioni e class library gestita dall’Application Diagram verrá poi gestita con una reference fra i progetti Visual Studio, cosí come ogni reference effettuata dai progetti si riflette sul diagramma tramite la visualizzazione della connessione. Il supporto two-way aderisce a quanto giá presente negli strumenti di design fino dalla versione 2005. La descrizione delle impostazioni relative ai progetti di tipo class library viene poi memorizzata in file .SDM direttamente nel progetto Visual Studio che rappresenta la dll stessa. 
&lt;p&gt;Ad esempio, partendo da un semplice esempio, é possibile rappresentare i progetti di tipo Class Library che appaiono nella toolbox dopo l&amp;#39;installazione dei Power Tools. 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2008ArchitectPower_E3EE/1VSTS2008PowerToolsAD2.jpg"&gt;&lt;img height="354" alt="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2008ArchitectPower_E3EE/1VSTS2008PowerToolsAD_thumb.jpg" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VISUALSTUDIO2008.netfwcf3.5_1684/clip_image024.jpg" width="426" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;Ogni connessione fra applicazioni e class library verrá poi gestita con una reference fra i progetti Visual Studio, cosí come ogni reference effettuata dai progetti si riflette sul diagramma tramite la visualizzazione della connessione. 
&lt;p&gt;Tempo fa ho eseguito l&amp;#39;upgrade della nostra soluzione (presentata a DevCon 2005 e DevCon 2007) composta ormai da una settantina di progetti Visual Studio in unica solution: si veda il post &lt;a href="http://blogs.devleap.com/rob/archive/2007/05/10/upgrade-to-orcas-beta-1.aspx"&gt;http://blogs.devleap.com/rob/archive/2007/05/10/upgrade-to-orcas-beta-1.aspx&lt;/a&gt;. 
&lt;p&gt;Dopo aver montato i Power Tool ho deciso di ridisegnare AD e DD facendo uso dei progetti di tipo class library. 
&lt;p&gt;Giustamente il risultato che mi si é presentato riaprendo il diagramma dopo l&amp;#39;installazione é il seguente 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2008ArchitectPower_E3EE/4VSTS2008PowerToolsEMADClassLibraryPre2.jpg"&gt;&lt;img height="275" alt="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2008ArchitectPower_E3EE/4VSTS2008PowerToolsEMADClassLibraryPre_thumb.jpg" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VISUALSTUDIO2008.netfwcf3.5_1684/clip_image025.jpg" width="498" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;In pratica l&amp;#39;AD si é accorto delle varie reference&amp;nbsp;a progetti class library dai progetti reali e ha rappresentato le &amp;quot;figurine&amp;quot; e le relative connection sul diagramma. I nomi dei progetti sono gli stessi dei nomi reali dei progetti .csproj a cui sono stati tolti in automatico, come da prassi, i &amp;quot;.&amp;quot;. 
&lt;p&gt;Per eliminare le Generic Application che avevamo usato come placeholder nella versione 2005 occorre procedere eliminando prima tutti i file .SDM (delle generic application) dalla solution di Visual Studio e poi eliminare dal diagramma&amp;nbsp;i relaitivi elementi grafici. 
&lt;p&gt;Gli SDM relativi alle applicazioni di tipo Class Library vengono memorizzati direttamente nel relativo progetto Visual Studio, come accade da sempre per i tipi di applicazioni gestiti dall&amp;#39;AD. 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2008ArchitectPower_E3EE/3VSTS2008PowerToolsReference4.jpg"&gt;&lt;img height="443" alt="http://devlab.devleap.it/RobertoB/Immagini/Posts/VisualStudioTeamSystem2008ArchitectPower_E3EE/3VSTS2008PowerToolsReference_thumb.jpg" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/VISUALSTUDIO2008.netfwcf3.5_1684/clip_image026.jpg" width="356" border="0" /&gt;&lt;/a&gt; 
&lt;p&gt;Altra operazione che avevamo fatto come workaround era stata quella di legare le class library dello strato DAL al database, operazione non piú necessaria in quanto il legame fra applicazione e DB sta giustamente nell&amp;#39;applicazione principale (Windows Form, WPF, ASP.NET che sia) ove infatti, da sempre, sono memorizzate le connection string nei rispettivi file .config. 
&lt;p&gt;Alla prossima&lt;/p&gt;&lt;img src="http://blogs.devleap.com/aggbug.aspx?PostID=18122" width="1" height="1"&gt;</content><author><name>rob</name><uri>http://blogs.devleap.com/members/rob.aspx</uri></author></entry><entry><title>Sviluppo Mobile: Costruire una propria libreria</title><link rel="alternate" type="text/html" href="http://blogs.devleap.com/articolidevleap/archive/2007/08/23/sviluppo-mobile-costruire-una-propria-libreria.aspx" /><id>http://blogs.devleap.com/articolidevleap/archive/2007/08/23/sviluppo-mobile-costruire-una-propria-libreria.aspx</id><published>2007-08-23T16.41.00Z</published><updated>2007-08-23T16.41.00Z</updated><content type="html">&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;di Roberto Brunetti 
&lt;p&gt;Roberto è un libero professionista del gruppo DevLeap (www.devleap.com) sul cui sito si trovano articoli e blog tecnici sulle tecnologie legate allo sviluppo software in .NET. E’ specializzato in ASP.NET, Sviluppo mobile, Architetture distribuite e Visual Studio Team System. E’ l’autore del libro ASP.NET Full Contact edito da Mondadori Informatica e numerose pubblicazioni su riviste del settore. Ha partecipato come speaker a numerose conferenze del settore ed è MCT da 1997. È il fondatore della community &lt;a href="http://www.thinkmobile.it/"&gt;www.ThinkMobile.it&lt;/a&gt; dedicata allo sviluppo mobile. 
&lt;p&gt;Dopo vari articoli su SQLCE 3.0 (che diventa installabile anche su Desktop con SQL Compact Edition 3.1) è arrivato il momento di dare uno sguardo alla scrittura di una propria libreria di classi per facilitare lo sviluppo di applicazioni. Questo articolo vuole essere una panoramica delle potenzialità spesso ignorate di Visual Studio 2005, non tanto per la produzione automatica di righe di codice (tecnica tra l’altro pericolosa in caso di grandi volumi di dati), quanto per la versatilità nella scrittura della libreria. 
&lt;p&gt;Sembra un articolo introdottivo, e in parte lo è, ma i concetti che vorrei passare, soprattutto dopo la prima parte, spero servano a sviluppare più velocemente testando l’applicazione sul desktop e con strumenti evoluti piuttosto che fare F5 e testare l’applicazione su device o emulatori. 
&lt;p&gt;In sequenza affronteremo la scrittura da zero di una classe molto semplice per leggere file di configurazione, feature assente nel .NET Compact Framework 2.0. Questo semplicissimo scheletro ci farà da guida per affrontare le modalità con cui noi di DevLeap (&lt;a href="http://www.devleap.com/"&gt;www.devleap.com&lt;/a&gt;) sviluppiamo applicazioni mobile. Cercheremo di scrivere e testare la libreria direttamente sul desktop per poi farne una analisi con gli strumenti di Visual Studio Team System esattamente come se fosse una libreria desktop. 
&lt;p&gt;Non è nel mio stile fare un articolo passo passo in quanto spesso preferisco cercare di andare in profondità sugli argomenti lasciando poi al lettore la fantasia di implementazione. Questa volta farò uno strappo alla regola e partiremo da zero in modo da mettere insieme i vari pezzi. Questo articolo non vuole essere però una guida per neofiti, quanto mettere in evidenza le potenzialità di uno strumento facendo capire passo passo gli step di sviluppo che adottiamo. 
&lt;p&gt;“Mi suona strano iniziare così”: aprite Visual Studio e create un nuovo progetto (utilizzeremo C#, ma il tutto è facilmente adattabile a VB.NET) 
&lt;p&gt;Creiamo un progetto C# - Smart Device di tipo libreria: scegliere la piattaforma (Pocket PC 2003, SmartPhone 2003, Windows CE 5.0, o Windows Mobile 5.0 xxx) è un dettaglio tralasciabile; come sapete questa selezione serve solo a utilizzare un template di Visual Studio che prepara lo scheletro applicativo con le reference corrette e qualche vincolo per evitare di usare librerie che potrebbero non girare sulla piattaforma target; per esempio, se scegliete Pocket PC 2003 non si vedranno le librerie Windows Mobile 5.0 nell’elenco delle librerie sotto Add Reference. In ogni caso, il codice che viene prodotto dalla compilazione è codice IL (o CIL) e come tale può girare ovunque giri il runtime del .NET Compact Framework 2.0. Nel caso di progetti “Device Application” la scelta, che ancora una volta non è vincolante, è più utile in quanto il designer di Visual Studio visualizza i form all’interno di device aderenti, come look &amp;amp; feel, alla piattaforma scelta. Ripeto: la scelta non è vincolante, ma è solo una facilitazione per trovare Reference e designer “adatti” alla piattaforma. Con Visual Studio 2005 è ancora possibile modificare la piattaforma scelta per un progetto dopo la creazione: è sufficiente premere tasto destro sul progetto e scegliere – Change Target Platform; volendo si può agire anche manualmente nei file di progetto in formato XML per allargare la scelta di possibili piattaforme. 
&lt;p&gt;Scelgo Windows Mobile 5.0, posiziono il tutto sotto c:\temp, nomino la Solution DevLeap.Sample, e il progetto DevLeap.Library.Mobile. Solution e progetto hanno nomi diversi semplicemente perché successivamente aggiungeremo altri progetti alla solution in modo da avere un client di test e progetti desktop per testare la nostra libreria. 
&lt;p&gt;Naming convention a parte questa la maschera di creazione progetto: 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/SviluppoMobileCostruireunaproprialibreri_1048F/clip_image0022.gif"&gt;&lt;img height="176" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/SviluppoMobileCostruireunaproprialibreri_1048F/clip_image0021.gif" width="240" border="0" alt="" /&gt;&lt;/a&gt; 
&lt;p&gt;Appena creato il progetto cancelliamo la mitica Class1.cs e creiamo un nuovo sorgente C# denonimato Utility.cs. 
&lt;p&gt;Il progetto, a questo punto, ha una classe Utility in cui aggiungeremo i metodi appunto utili J nelle nostre applicazioni mobile. Il namespace per default è giustamente DevLeap.Library.Mobile. 
&lt;p&gt;Rendiamo pubblica la classe in modo da poterla richiamare dall’esterno e, se volete, sealed in modo da non poterla derivare ulteriormente e da non doverci preoccupare nella sua definizione di eventuali politiche di inheritance. 
&lt;p&gt;Questo il nostro progetto: 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/SviluppoMobileCostruireunaproprialibreri_1048F/clip_image0042.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="157" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/SviluppoMobileCostruireunaproprialibreri_1048F/clip_image0041.jpg" width="240" border="0" alt="" /&gt;&lt;/a&gt; 
&lt;p&gt;Fino a qui niente di nuovo immagino. Aggiungiamo un metodo per leggere il classico file di configurazione. Solitamente utilizzo questa tecnica: espongo un metodo GetAppConfigString che riceve in input il nome del file config e la key da leggere. Non calcolo in automatico il nome del config, come fa il .NET Framework completo per evitare “casini” di concatenazione sul nome del file da trovare; questo evita problemi di naming sul file .config che hanno, ad esempio, creato non pochi problemi nelle vecchie versioni di OpenNETCF. Preferisco passare un parametro in più piuttosto che lasciare alla libreria l’onere di trovare il nome corretto. Se preferite calcolare il nome in automatico, i metodi GetExecutingAssembly e GetCallingAssembly della classe Assembly possono darvi una mano. 
&lt;p&gt;Per evitare la lettura del config da disco (pardon, da scheda SD J) ad ogni richiesta, metto in cache il documento XML alla prima lettura. Ci servono quindi una variabile statica _xmlDoc (per rispettare la naming convention) e una variabile di tipo Object su cui effettuare la sincronizzazione in caso di applicazione multithread. 
&lt;p&gt;Ecco la prima parte del codice che inserisce in cache un XmlDocument nel caso in cui sia null: 
&lt;p&gt;if (Utility._xmlDoc == null) 
&lt;p&gt;{ 
&lt;p&gt;lock (_xmlDocSyncLock) 
&lt;p&gt;{ 
&lt;p&gt;if (Utility._xmlDoc == null) 
&lt;p&gt;{ 
&lt;p&gt;XmlDocument xmlDoc = new XmlDocument(); 
&lt;p&gt;string xmlDocPath = Utility.GetAppPath() + &amp;quot;\\&amp;quot;&lt;br /&gt;+ configName; 
&lt;p&gt;XmlTextReader tr = new XmlTextReader(xmlDocPath); 
&lt;p&gt;xmlDoc.Load(tr); 
&lt;p&gt;tr.Close(); 
&lt;p&gt;_xmlDoc = xmlDoc; 
&lt;p&gt;} 
&lt;p&gt;} 
&lt;p&gt;} 
&lt;p&gt;Prima di inserire il codice nel metodo corretto due informazione: stiamo usando un pattern .NET che, in questo caso, ci serve a caricare il documento XML nella variabile statica _xmlDoc. L’utilizzo del lock e della doppia if su _xmlDoc serve a evitare che più thread chiamanti vadano in conflitto durante l’assegnazione della variabile _xmlDoc. 
&lt;p&gt;Per leggere il file .config in formato XML (il classico file .config di .NET) ho utilizzato un XmlDocument che viene alimentato da un XmlTextReader. Per rintracciare la path del file config si utilizza un’altra funzione da aggiungere alla nostra libreria (Utility.GetAppPath) che vedremo tra un attimo. 
&lt;p&gt;Una volta assegnato il documento XML alla nostra variabile statica si procede alla sua lettura; ecco il metodo completo: 
&lt;p&gt;using System; 
&lt;p&gt;using System.Collections.Generic; 
&lt;p&gt;using System.Text; 
&lt;p&gt;using System.Xml; 
&lt;p&gt;namespace DevLeap.Library.Mobile 
&lt;p&gt;{ 
&lt;p&gt;public sealed class Utility 
&lt;p&gt;{ 
&lt;p&gt;private static XmlDocument _xmlDoc; 
&lt;p&gt;private static Object _xmlDocSyncLock = new Object(); 
&lt;p&gt;public static string GetAppConfigString(string configName,&lt;br /&gt;string key) 
&lt;p&gt;{ 
&lt;p&gt;if (Utility._xmlDoc == null) 
&lt;p&gt;{ 
&lt;p&gt;lock (_xmlDocSyncLock) 
&lt;p&gt;{ 
&lt;p&gt;if (Utility._xmlDoc == null) 
&lt;p&gt;{ 
&lt;p&gt;XmlDocument xmlDoc = new XmlDocument(); 
&lt;p&gt;string xmlDocPath = Utility.GetAppPath() + &amp;quot;\\&amp;quot;&lt;br /&gt;+ configName; 
&lt;p&gt;XmlTextReader tr = new XmlTextReader(xmlDocPath); 
&lt;p&gt;xmlDoc.Load(tr); 
&lt;p&gt;tr.Close(); 
&lt;p&gt;_xmlDoc = xmlDoc; 
&lt;p&gt;} 
&lt;p&gt;} 
&lt;p&gt;} 
&lt;p&gt;String value = &amp;quot;&amp;quot;; 
&lt;p&gt;XmlNode node = _xmlDoc.SelectSingleNode&lt;br /&gt;(&amp;quot;//configuration//appSettings//add[@key=&amp;#39;&amp;quot; + &lt;br /&gt;key + &amp;quot;&amp;#39;]/@value&amp;quot;); 
&lt;p&gt;if (node != null) 
&lt;p&gt;{ 
&lt;p&gt;value = node.Value.ToString(); 
&lt;p&gt;} 
&lt;p&gt;return value; 
&lt;p&gt;} 
&lt;p&gt;} 
&lt;p&gt;} 
&lt;p&gt;Per leggere la “key” ricevuta come argomento all’interno dell’albero dei nodi ho utilizzato una espressione XPath tramite il metodo SelectSingleNode. Nel caso in cui non trovi l’elemento di configurazione ho deciso di restituire String.Empty. 
&lt;p&gt;Inseriamo a questo punto la funzione GetAppPath: 
&lt;p&gt;public static string GetAppPath() 
&lt;p&gt;{ 
&lt;p&gt;#if All 
&lt;p&gt;return Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase); 
&lt;p&gt;#else 
&lt;p&gt;return Path.GetDirectoryName(Assembly.GetCallingAssembly().GetName().CodeBase); 
&lt;p&gt;#endif 
&lt;p&gt;} 
&lt;p&gt;Vedremo più avanti l’utilizzo della #if (compilazione condizionale); in pratica, visto che su Windows Mobile caricare tante DLL può essere un problema, solitamente scrivo l’applicazione su diversi layer (UI, BIZ, DAL, Factory, Entity e così via) e poi li confeziono in un unico exe sui device che possono avere il problema di caricamento. Vedremo come fare più avanti. Per adesso la #if All serve a chiamare il metodo Assembly.GetExecutingAssembly nel caso in cui il progetto sia confezionato con un unico exe oppure Assembly.GetCallingAssembly per ottenere l’assembly chiamante di questa libreria. In entrambi i casi prelevo poi il CodeBase che rappresenta la directory da cui è stato letto l’assembly in questione. 
&lt;p&gt;Per poter usare la classe Path e la classe Assembly occorrono due using (le reference sono già corrette come le ha impostate il template di Visual Studio): System.IO per Path e System.Reflection per Assembly. Ovviamente qualunque altra tecnica (compreso passare il path completo al file .config sono ugualmente valide). 
&lt;p&gt;A questo punto creiamo un progetto exe che utilizza la libreria: per uniformità creiamo un progetto Device Application per Windows CE 5.0 che chiameremo Applicazione. All’interno del progetto metteremo anche il file .config che useremo dalla libreria. Ho aggiunto il progetto dalla solution con tasto destro Add New Project e poi inserito un file xml chiamato Applicazione.Config. 
&lt;p&gt;Ecco il risultato 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/SviluppoMobileCostruireunaproprialibreri_1048F/clip_image0062.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="157" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/SviluppoMobileCostruireunaproprialibreri_1048F/clip_image0061.jpg" width="240" border="0" alt="" /&gt;&lt;/a&gt; 
&lt;p&gt;Il nome del file config, per uniformità, è Applicazione.config. Se preferite mantenere la naming convention delle applicazioni desktop usate app.config: occorre però stare attenti in quanto successivamente cercheremo di utilizzare questa libreria sul desktop e così facendo ritorneremo nel problema accennato in precedenza: il calcolo del nome del file config automatico. 
&lt;p&gt;A questo punto si può inserire un pulsante di test sul form per provare a leggere il file di configurazione; prima di aggiungere il codice occorre ovviamente una reference dal progetto Applicazione al progetto DevLeap.Library.Mobile. Il form conterrà poi il codice per leggere il .config che, com’è intuibile, è il seguente: 
&lt;p&gt;using System; 
&lt;p&gt;using System.Collections.Generic; 
&lt;p&gt;using System.ComponentModel; 
&lt;p&gt;using System.Data; 
&lt;p&gt;using System.Drawing; 
&lt;p&gt;using System.Text; 
&lt;p&gt;using System.Windows.Forms; 
&lt;p&gt;using DevLeap.Library.Mobile; 
&lt;p&gt;namespace Applicazione 
&lt;p&gt;{ 
&lt;p&gt;public partial class Form1 : Form 
&lt;p&gt;{ 
&lt;p&gt;public Form1() 
&lt;p&gt;{ 
&lt;p&gt;InitializeComponent(); 
&lt;p&gt;} 
&lt;p&gt;private void cmdReadConfig_Click(object sender, EventArgs e) 
&lt;p&gt;{ 
&lt;p&gt;MessageBox.Show(Utility.GetAppConfigString&lt;br /&gt;(&amp;quot;Applicazione.config&amp;quot;, &amp;quot;Test&amp;quot;)); 
&lt;p&gt;} 
&lt;p&gt;} 
&lt;p&gt;} 
&lt;p&gt;Prima di eseguire il progetto su un emultatore o su un device occorre marcare il file Applicazione.config come Build Action = Content e come Copy To Output Directory = Always oppure Copy if Newer; queste impostazioni si scelgono dalla mascherina delle proprietà del file all’interno del progetto di Visual Studio e consentono appunto di eseguire il deploy come contenuto (non come compilazione ovviamente) del file di configurazione. 
&lt;p&gt;Eseguito il deploy e premuto il pulsante di test sul form (che ho chiamato cmdReadConfig) otteniamo ovviamente la stringa memorizzata nel file .config. 
&lt;p&gt;&lt;b&gt;Proviamo quindi ad andare oltre&lt;/b&gt;: una volta creata la propria libreria, così come gli altri strati dell’applicazione occorre testare il tutto; testare il codice sul device è una procedura abbastanza lunga: per ogni modifica occorre rifare il deploy dell’applicazione, riavviare il debug (non c’è Edit &amp;amp; Continue sul device !). Debuggando il tutto sull’emulatore si va un po’ più veloci (soprattutto se collegate l’emulatore via DMA e usate la tastiera del pc per l’input), ma abbiamo sempre il problema di deploy per ogni modifica, l’impossibilità di usare Edit &amp;amp; Continue e soprattutto utilizziamo un “coso mobile” senza un file system comodo da visualizzare e editare. 
&lt;p&gt;Visual Studio Team System offre molti strumenti che facilitano il compito durante il test funzionale e il test di performance...ma…purtroppo questi strumenti non girano in ambiente Windows CE. Lo sviluppatore “accanito” però non si fa spaventare da questa limitazione della prima versione di Team System e si organizza J. Come ? Così ! 
&lt;p&gt;Il Compact Framework è una versione ridotta del .NET Framework quindi, a parte qualche funzionalità specifica del .NET CF che non esiste su .NET FW completo (vedi IrDA ad esempio), tutto quello che funziona sul .NET CF funziona anche sul .NET FW completo. È disponibile un runtime del .NET CF 2.0 (anche della 1.0 in realtà) per processore X86 che ci consente di far girare il codice IL (o CIL) su Desktop. 
&lt;p&gt;Anche per SQLCE versione 3.0 è valido questo ragionamento. Si possono aprire e gestire file SDF sia da Visual Studio che da Sql Server 2005 Management Studio. Le librerie di SQLCE esistono anche per processore X86. Con SQL Compact Edition 3.0 (la 3.1 che al momento di scrittura di questo articolo – Dic 2006 – sta per uscire gira nativamente su desktop) è possibile, con poco lavoro, fare una reference da un progetto desktop alle librerie versione X86 per eseguire il codice di accesso ai dati su desktop; a tal proposito si veda il mio post di dicembre 2005; il post è su Team System, leggete l’ultima parte: &lt;a href="http://blogs.devleap.com/rob/archive/2005/12/29/6428.aspx"&gt;http://blogs.devleap.com/rob/archive/2005/12/29/6428.aspx&lt;/a&gt; 
&lt;p&gt;Bene, abbiamo affermato che il codice si può testare sul desktop (vedremo come evitare l’utilzzo di barcode reader o librerie specifiche per l’ambiente mobile…tutto non si può avere J), vediamo come fare sul nostro semplicissimo progetto mobile composto da un exe e da una dll. Questa logica si può applicare, ed è quello che facciamo sui nostri progetti mobile reali, ad architetture più complesse seguendo sempre questi passi. 
&lt;p&gt;La sfiga (termine tecnico che sta a indicare generalmente una forma acuta di sfortuna) vuole che non si possa prendere il codice compilato per farlo girare sul desktop: questo non perché i compilatori siano diversi (vi garantisco che sono identici, anzi è proprio lo stesso csc.exe o vbc.exe a compilare i progetti mobile) ma perché le reference verso le librerie del framework sono diverse. Occorre quindi ricompilare il codice con le reference corrette per l’ambiente desktop. 
&lt;p&gt;Pronti? Iniziamo. 
&lt;p&gt;Per prima cosa creiamo un progetto di tipo Class Library normale (per il desktop) che per convenzione si chiamerà DevLeap.Library.Mobile.Desktop, così manteniamo i nomi allineati. Dopo la creazione togliamo tutti sorgenti all’interno e facciamo le stesse reference del progetto mobile: le reference vanno appunto fatte alle librerie del FW completo. Quindi se trovo una reference verso System.Xml nel progetto mobile farò una reference verso System.Xml del FW completo, se trovo un riferimento verso System.Windows.Form mobile farò una reference verso System.Windows.Form del FW completo. 
&lt;p&gt;Poi aggiungiamo i sorgenti del progetto mobile (Utility.cs nel nostro semplice caso). Nessuno di noi ha voglia di avere lo stesso codice in due posti diversi quindi non aggiungete il file normalmente, ma come LINK: questo consente di mantenere il sorgente “vero” nel progetto mobile, ma poterlo compilare, usare e modificare anche dal progetto desktop. 
&lt;p&gt;Dalla mascherina di Add Existing Item andate nella directory del progetto mobile (DevLeap.Library.Mobile nel nostro caso), selezionate tutti i sorgenti e poi premere il pulsantino nascosto accanto a Add: questa la maschera 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/SviluppoMobileCostruireunaproprialibreri_1048F/clip_image0082.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="135" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/SviluppoMobileCostruireunaproprialibreri_1048F/clip_image0081.jpg" width="240" border="0" alt="" /&gt;&lt;/a&gt; 
&lt;p&gt;Fate un Add as Link e non Add altrimenti il sorgente selezionato viene copiato nel progetto, cosa da evitare appunto per non raddoppiare i sorgenti. 
&lt;p&gt;Questo vale anche per i file reference.cs, per i file di configurazione (sempre che debbano essere identici), per i file che rappresentano i form (basta linkare il Formxxx.cs, non occorre prendere anche .designer.cs e .resx) e per i controlli custom (anche in questo caso prendere solo il Controxxx.cs; VS si preoccupa di linkare anche i file designer e resx). 
&lt;p&gt;Date una compilata al progetto Desktop per vedere se abbiamo tutte le reference corrette. 
&lt;p&gt;Proseguiamo poi con la creazione del progetto exe allineato all’eseguibile mobile: creare un Windows Application Project e referenziare DevLeap.Library.Mobile.Desktop (occorre prendere il progetto desktop ovviamente). Cancellare Form1.cs e Program.cs e poi aggiungere con la stessa tecnica dell’Add As Link Form1.cs, Applicazione.config e Program.cs dal progetto Applicazione. Per uniformità chiamerei il progetto desktop Applicazione.Desktop. 
&lt;p&gt;Questa la situazione attuale: 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/SviluppoMobileCostruireunaproprialibreri_1048F/clip_image0102.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="240" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/SviluppoMobileCostruireunaproprialibreri_1048F/clip_image0101.jpg" width="105" border="0" alt="" /&gt;&lt;/a&gt; 
&lt;p&gt;Come si nota i progetti desktop hanno i sorgenti dei rispettivi progetti mobile come Link (c’è un simbolino accanto al file) e le rispettive Reference. Ultima cosa: sul file Applicazione.config nel progetto desktop occorre impostare (come avevamo fatto per il progetto mobile) Build Action = Content e Copy to Output Directory = Copy Always o Copy If Newer. 
&lt;p&gt;Curiosi ? Avviate il progetto Applicazione.Desktop (fate tasto destro sul progetto, Debug, Start new instance) e come per magia ecco un form su XP (o Vista) con il form Mobile !!! 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/SviluppoMobileCostruireunaproprialibreri_1048F/clip_image0112.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="240" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/SviluppoMobileCostruireunaproprialibreri_1048F/clip_image0111.jpg" width="196" border="0" alt="" /&gt;&lt;/a&gt; 
&lt;p&gt;Questa tecnica funziona per qualunque controllo mobile supportato anche sul desktop. Ad esempio aggiungiamo un menù sul form mobile per capire cosa succede. Un consiglio: anche se si possono aprire i sorgenti linkati dal progetto .Desktop vi consiglio di editare i form sempre partendo dal progetto mobile; questo perché altrimenti la Toolbox di Visual Studio 2005 vi presenta tutti i controlli Windows.Form dell’ambiente desktop (giustamente) molti dei quali non esistono sul .NET CF. Aprendo invece i form dal progetto mobile avrete la toolbox corretta. Non preoccupatevi se ogni tanto riceverete il messaggio di errore “This document is opened by another project”: indica semplicemente che avete aperto un sorgente da un progetto e poi avete provato ad aprirlo da un altro progetto; è solo un warning che giustamente vi avverte che lavorate su un sorgente già aperto. 
&lt;p&gt;Per esempio: ho inserito sul form, dal progetto mobile, un po’ di controlli e un menù mobile. Questo il risultato sul desktop 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/SviluppoMobileCostruireunaproprialibreri_1048F/clip_image0122.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="240" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/SviluppoMobileCostruireunaproprialibreri_1048F/clip_image0121.jpg" width="176" border="0" alt="" /&gt;&lt;/a&gt; 
&lt;p&gt;Ovviamente il menù esce stile XP e non stile mobile e non ci sono le due soft key per rappresentare il menù. 
&lt;p&gt;Con il progetto desktop si può, solo per citare alcuni punti: 
&lt;p&gt;1) Lavorare con l’interfaccia 
&lt;p&gt;2) Testare il codice 
&lt;p&gt;3) Fare Edit &amp;amp; Continue durante il debug 
&lt;p&gt;4) Se l’applicazione lavora con il file system si può controllare il lavoro direttamente nella directory bin sul file system della macchina di sviluppo 
&lt;p&gt;5) Se l’applicazione scrive e legge file si possono editare dal file system del PC senza dover usare ActiveSync per copiare i file da e verso il device. 
&lt;p&gt;Ci sono una serie di cose che non si possono fare. Ad esempio 
&lt;p&gt;1) Testare librerie specifiche mobile come ad esempio BarCode Reader 
&lt;p&gt;2) Testare IrDA 
&lt;p&gt;3) Testare librerie Windows Mobile per Pocket Outlook 
&lt;p&gt;In questi casi uso la sequente tecnica: inserisco una direttiva di compilazione sul progetto Desktop oppure sfrutto le direttive #Pocket PC già inserite da Visual Studio sui progetti mobile per eliminare le righe che non funzionano sul desktop. 
&lt;p&gt;Ad esempio, in un applicativo che stiamo scrivendo adesso e che fa uso di librerie per lettori di codice a barre, questo è il codice per eliminare le parti non ammesse sul desktop. Siamo nel load di un form nello strato di User Interface che è divisa dall’eseguibile per essere sfruttata da più risoluzioni video. 
&lt;p&gt;private void MainForm_Load(object sender, EventArgs e) 
&lt;p&gt;{ 
&lt;p&gt;UI.DummyCalls(); 
&lt;p&gt;#if PocketPc 
&lt;p&gt;UI.CreateBrowserForm(new BrowserForm()); 
&lt;p&gt;#endif 
&lt;p&gt;UI.ChangeState(ComeurOnline.Maui.UI.Common.BaseUI.FlowState.Login, txtRequest, lblError, lblRequest, treeLog, SendActionStepOutputMessageResponseStatus.Information, null, null, lblUserId, txtUserId, lblUserPassword, txtUserPassword, cmdLogin, cmdLogout); 
&lt;p&gt;#if PocketPc 
&lt;p&gt;// If we can initialize the Reader 
&lt;p&gt;if (BarCodeReader.InitReader()) 
&lt;p&gt;{ 
&lt;p&gt;// Create a new delegate to handle scan notifications 
&lt;p&gt;this._barCodeEventHandler = new&lt;br /&gt;EventHandler(BarCodeReader_ReadNotify); 
&lt;p&gt;// Set the event handler of the Scanning class to our delegate 
&lt;p&gt;BarCodeReader.BarCodeEventHandler = this._barCodeEventHandler; 
&lt;p&gt;// Attach to activate and deactivate events 
&lt;p&gt;// this.Activated += new EventHandler(ReaderForm_Activated); 
&lt;p&gt;// Start a read on the reader 
&lt;p&gt;BarCodeReader.StartRead(); 
&lt;p&gt;} 
&lt;p&gt;else 
&lt;p&gt;{ 
&lt;p&gt;// Error 
&lt;p&gt;UI.ChangeState(ComeurOnline.Maui.UI.Common.BaseUI.FlowState.CommunicationError, txtRequest, lblError, lblRequest, treeLog, SendActionStepOutputMessageResponseStatus.Error, null, &amp;quot;BarCode Reader Error&amp;quot;, lblUserId, txtUserId, lblUserPassword, txtUserPassword, cmdLogin, cmdLogout); 
&lt;p&gt;return; 
&lt;p&gt;} 
&lt;p&gt;#endif 
&lt;p&gt;} 
&lt;p&gt;Come si nota, Visual Studio “dipinge” di grigio il codice sotto compilazione condizionale. In questo caso, semplicemente “attiviamo” la nostra libreria per la lettura del codice a barre nel caso Pocket Pc: questa direttiva di compilazione è già inserita da VS 2005 in tutti i progetti mobile. 
&lt;p&gt;Anche se non è argomento di questo articolo, avere un progetto desktop per ogni progetto mobile della solution (un lavoro che costa circa 1 oretta di lavoro su un progetto reale: cronometrati 1 ore e 15 minuti sul progetto che stiamo seguendo adesso composto da 9 layer e quindi 9 progetti in cascata sul client mobile) consente poi di usare gli strumenti di Visual Studio Team System come Unit Testing, Code Coverage e Performance Session. &lt;br /&gt;
&lt;p&gt;&lt;strong&gt;Update: Visual Studio 2008 consente&amp;nbsp;la creazione e eseguzione&amp;nbsp;di Unit Test direttamente dalla versione Professional. Gli unit test sono eseguibili anche su device e emulatore. In ogni caso mancano gli strumenti integrati di code coverage e performance session.&lt;/strong&gt; 
&lt;p&gt;Per completezza riporto gli screenshot in cui dovrebbe essere facilmente leggibile anche il codice di Unit Test sul metodo GetAppConfigString, il risultato del Code Coverage del test e la maschera di solo sommario della Performance Session basata sull Unit Test. 
&lt;p&gt;Unit Test su GetAppConfigString (UtilityGetAppConfigStringTest): 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/SviluppoMobileCostruireunaproprialibreri_1048F/clip_image0142.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="165" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/SviluppoMobileCostruireunaproprialibreri_1048F/clip_image0141.jpg" width="240" border="0" alt="" /&gt;&lt;/a&gt;&amp;nbsp;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Code Coverage su Unit Test UtilityGettAppConfigStringTest &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/SviluppoMobileCostruireunaproprialibreri_1048F/clip_image0162.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="184" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/SviluppoMobileCostruireunaproprialibreri_1048F/clip_image0161.jpg" width="240" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Performance Session su Unit Test UtilityGettAppConfigStringTest &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/SviluppoMobileCostruireunaproprialibreri_1048F/clip_image0182.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="184" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/SviluppoMobileCostruireunaproprialibreri_1048F/clip_image0181.jpg" width="240" border="0" alt="" /&gt;&lt;/a&gt; 
&lt;p&gt;Per avere un’idea del carico sotto stress si può simulare l’accesso allo unit test da parte di uno o più utenti (simulazione valida anche per più thread) per un tempo stabilito. In VSTS questa tecnica implica l’utilizzo di un Load Test basato sullo Unit Test; sono 3 click di mouse per creare la versione base: 
&lt;p&gt;&lt;a href="http://devlab.devleap.it/RobertoB/Immagini/Posts/SviluppoMobileCostruireunaproprialibreri_1048F/clip_image0202.jpg"&gt;&lt;img style="BORDER-RIGHT:0px;BORDER-TOP:0px;BORDER-LEFT:0px;BORDER-BOTTOM:0px;" height="143" src="http://devlab.devleap.it/RobertoB/Immagini/Posts/SviluppoMobileCostruireunaproprialibreri_1048F/clip_image0201.jpg" width="240" border="0" alt="" /&gt;&lt;/a&gt; 
&lt;p&gt;In un solo minuto abbiamo fatto 36.023 chiamate alla nostra funzione e direi che dai risultati (che non posso incollare in questo articolo per motivi di spazio, ma che potete analizzare voi stessi scaricando gli esempio) il tutto gira molto bene...e ci mancherebbe visto che abbiamo scritto una sola funzione J Applicate il ragionamento ad un progetto reale e tutto il tempo che risparmiate nello sviluppo su desktop potete investirlo in test più accurati. 
&lt;p&gt;N.B. Nel Load Test ovviamente otteniamo dei warning (39 threshold violation per l’esattezza) sul processore in quanto spesso il processore della macchina va oltre il 95%: la situazione è più che normale visto che “stressante e stressato” (Test e applicazione J) sono sulla stessa macchina. 
&lt;p&gt;Con pochi passaggi, avendo un progetto desktop, siamo in grado di testare il codice, di vedere cosa implica l’esecuzione del codice e possiamo mettere sotto stress il tutto per capire cosa succede nell’utilizzo reale dell’applicazione. Ovviamente i dati di performance riguardano l’ambiente desktop, ma facendo gli opportuni “scaling” si può come girerà nell’ambiente mobile. 
&lt;p&gt;Il codice completo, compreso il semplice Unit Test, il Load Test per testare il carico, una Performance Session per capire l’allocazione di memoria e i tempi di chiamate, e l’analisi dinamica del codice con Code Coverage, sono disponibili su &lt;a href="http://www.thinkmobile.it/files"&gt;www.thinkmobile.it/files&lt;/a&gt;: il file da scricare, previa registrazione al sito, è Articolo Infomedia Lib Mobile.zip. 
&lt;p&gt;Sperando di avervi semplificato la vita durante lo sviluppo delle parti core di una applicazione mobile, dandovi la possiblità con un semplice “lavoretto” di testare il 90% della soluzione e lasciando sul device o emulatore (l’emulatore comunque non avrebbe BarCode Reader ad esempio) solo la parte finale dei test vi rimando alla nostra conferenza &lt;a href="http://devcon2007.devleap.com/"&gt;http://devcon2007.devleap.com&lt;/a&gt; dove avremmo modo di analizzare in varie sessioni anche lo sviluppo mobile oltre a .NET 3.0 per Desktop e Server. 
&lt;p&gt;Reference: 
&lt;p&gt;OpenNETCF: Libreria Shared Source scaricabile da &lt;a href="http://www.opennetcf.org/"&gt;www.opennetcf.org&lt;/a&gt; 
&lt;p&gt;Articolo su Progetti desktop/mobile in VSTS : &lt;a href="http://blogs.devleap.com/rob/archive/2005/12/29/6428.aspx"&gt;http://blogs.devleap.com/rob/archive/2005/12/29/6428.aspx&lt;/a&gt; 
&lt;p&gt;Esempi di codice completi che ripercorrono l’articolo 
&lt;p&gt;&lt;a href="http://www.thinkmobile.it/files"&gt;www.thinkmobile.it/files&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.devleap.com/aggbug.aspx?PostID=17797" width="1" height="1"&gt;</content><author><name>rob</name><uri>http://blogs.devleap.com/members/rob.aspx</uri></author></entry><entry><title>Visual Studio Orcas for Mobile Dev</title><link rel="alternate" type="text/html" href="http://blogs.devleap.com/articolidevleap/archive/2007/05/11/visual-studio-orcas-for-mobile-dev.aspx" /><id>http://blogs.devleap.com/articolidevleap/archive/2007/05/11/visual-studio-orcas-for-mobile-dev.aspx</id><published>2007-05-11T10.36.27Z</published><updated>2007-05-11T10.36.27Z</updated><content type="html">&lt;p&gt;&lt;strong&gt;Prime&amp;nbsp; impressioni sulla Beta1 di Orcas. &lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Ho installato il tutto su una macchina VMWare dedicando 1.4 GB alla Virtual Machine memore della quantità di memoria che "ciucciava" la CTP di Marzo.&lt;/p&gt; &lt;p&gt;Dalle prime prove mi sembra molto più snello e non supero quasi mai il primo GB di memoria: non c'è paragone neanche sulla velocità.&lt;/p&gt; &lt;p&gt;Nella mia installazione non appariva la toolbox e neanche la tollbat Standard: basta ovviamente attivarle e appaiono.&lt;/p&gt; &lt;p&gt;Nella virtual machine VPC scaricabile (ho preso la versione con VSTS e TFS) non c'è ActiveSync, quindi ho montato la 4.5. Manca anche il Windows Mobile 6.0 SDK come segnalato nei post precedenti: a MEDC hanno confermato che non ci sarà neanche nella versione finale e va installato a parte.&lt;/p&gt; &lt;p&gt;Il .NET CF 3.5 adesso installa le stringhe di risorse sul device/emulatore tramite un nuovo cab denominato NETCFv35.Messages.EN.CAB che si trova sotto x:\program files\Microsoft.NET\SDK\CompactFramework\v3.5\windowsce\Diagnostics.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;La creazione di un nuovo progetto presenta una nuova maschera, simile a quanto avveniva in VS 2003: non si sceglie il progetto dall'alberino delle varie solution disponibili, ma è sufficiente scegliere Smart Device: una volta scelto il tipo di progetto in una seconda maschera si sceglie la tipologia di piattaforma e poi la versione del .NET CF da utilizzare per le reference e per la distribuzione del runtime sul device. Si può optare per .NET CF 2.0 o per .NET CF 3.5.&lt;/p&gt; &lt;p&gt;N.B. le immagini incluse sono ridotte come dimensione: accanto ad ognuna il link verso la dimensione reale.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Questa la prima maschera:&lt;/p&gt; &lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6138/original.aspx" target="_blank"&gt;&lt;img src="http://thinkmobile.it/photos/orcas/images/6138/425x323.aspx"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Come si nota le piattaforme per cui è installato nativamente l'SDK sono Pocket PC 2003, Windows CE, Windows Mobile 5.0 for Pocket PC e SmartPhone.&lt;/p&gt; &lt;p&gt;Una volta scelta la piattaforma si sceglie la versione del .NET CF da utilizzare:&lt;/p&gt; &lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6139/original.aspx" target="_blank"&gt;&lt;img src="http://thinkmobile.it/photos/orcas/images/6139/425x323.aspx"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;Dopo la scelta della versione del .NET CF, come sempre scegliere Device Application, Class Library e così via per creare il tipo di progetto.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Il designer delle Windows Form (visto che WPF non è disponibile sul .NET CF 3.5) si presenta molto simile al precedente: si può scegliere il form factor da assegnare ad ogni form e ruotare lo schermo del designer come nella versione 2005 di VS.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6140/original.aspx" target="_blank"&gt;&lt;img src="http://thinkmobile.it/photos/orcas/images/6140/425x309.aspx"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Anche la toolbox si presenta più o meno identica. Questo l'elenco dei controlli:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6141/original.aspx" target="_blank"&gt;&lt;img src="http://thinkmobile.it/photos/orcas/images/6141/81x425.aspx"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;La configurazione dell'emulatore da Visual Studio prevede quanto conosciamo con l'attuale Device Emulator 2.0 e consente la gestione del livello della batteria: questa funzione risulta molto comoda per testare un'applicativo power-aware (come dovrebbero essere tutti): è inutile lanciare una operazione lunga di analisi sui dati, ad esempio, se resta il 2% di batteria.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6142/original.aspx" target="_blank"&gt;&lt;img src="http://thinkmobile.it/photos/orcas/images/6142/425x328.aspx"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;Molto interessante il nuovo Device Configuration Manager, primo fra gli strumenti per facilitare la configurazione di device e emulatori: ad oggi è necessario comporre i file .xml di provisioning e "installarli" tramite rapiconfig.exe. Con questo nuovo strumento risulta molto semplice leggere la configurazione, modificarla e vedere le differenze fra la configurazione desiderata e quella attuale. Si possono importare anche i nostri file di provisioning esistenti per una facile migrazione al nuovo strumento.  &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6144/original.aspx" target="_blank"&gt;&lt;img src="http://thinkmobile.it/photos/orcas/images/6144/425x284.aspx"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Risulta molto semplice così testare l'applicazione firmata o non firmata sulle varie configurazioni dei device One-Tier, Two-Tier, Locked, Prompt e così via.  &lt;p&gt;Tramite questo strumento è possibile visualizzare i certificati digitali installati su device e emulatori, installarne di nuovi e verificarne i dettagli. Una nota, i nomi dei certificate store sono cambiati: non abbiamo più il privileged e unprivileged, ma Privileged Store e Standard Store, dove il secondo rappresenta lo store per i certificati con cui le applicazioni possono girare in normal-mode su device two-tier.  &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6143/original.aspx" target="_blank"&gt;&lt;img src="http://thinkmobile.it/photos/orcas/images/6143/425x285.aspx"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Il .NET CF Remote Performance Monitor consente, nella nuova versione di fare un "attach to process" rendendo più semplice l'analisi di una porzioni di applicazione: la versione attuale deve lanciare l'applicazione e quindi ci costringe a visualizzare i dati complessivi di tutta l'applicazione fino a raggiungere il punto in cui si desidera effettuare le verifiche. La parte device-side viene installata in automatico dallo strumento senza bisogno di copiare manualmente i file nella directory \Windows: qualche problemino sulla mia Beta non consente di eseguire questa operazione in automatico e quindi ho dovuto comunque copiare i file a mano. I nuovi file device-side hanno nomi diversi dai precedenti e più precisamente sono: rtf3_5.dll e rtfhost3_5.exe. Tali file si trovano sempre nella directory dell'SDK del .NET CF 3.5 x:\program files\Microsoft.NET\SDK\CompactFramework\v3.5: ricordatevi di scegliere poi la directory corretta in base al processore del device; per gli emulatori si utilizza sempre la versione ARM.&lt;/p&gt; &lt;p&gt;Nella prossima immagine la directory con gli strumenti lato PC di sviluppo. Oltre al .NET CF RPM, troviamo LogViewer, già presente nella versione 2.0 SP1/SP2 e due nuovi strumenti:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6146/original.aspx" target="_blank"&gt;&lt;img src="http://thinkmobile.it/photos/orcas/images/6146/425x319.aspx"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Il primo NETCFCLRProfiler è una versione ridotta (e per la verità anche diversa) del Profiler del Framework completo. Consente di analizzare nel dettaglio un'applicazione in esecuzione: anche in questo caso ci si può "attaccare" ad un processo già avviato e l'installazione delle dll lato device è automatica (come sempre sono sfigato e ho dovuto copiare a mano clrpro3_5.dll sul device). Lo strumento visualizza anche sotto forma di flusso grafico le chiamate fra i vari metodi consentendo una semplice (si fa per dire quando si parla di profiling in generale) individuazione dei punti della call stack che possono dare problemi.&lt;/p&gt; &lt;p&gt;Il compact frameowrk 3.5 arriva con qualche dll in più per supportare LINQ e WCF (sempre in versione ridotta: entrambi sono c.a. 250KB come obiettivo nella versione finale) e i nomi dei cab sono stati leggermente rivisti.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6147/original.aspx" target="_blank"&gt;&lt;img src="http://thinkmobile.it/photos/orcas/images/6147/425x229.aspx"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;Nella System.ServiceModel si trovano le "porzioni" del motore di WCF e il binding basicHttpBinding, mentre in Microroft.ServiceModel.Channels.Mail.* il nuovo canale (non disponibile in WCF su desktop) WindowsMobileMailBinding che consente lo scambio di messaggi SOA sfruttando il canale della posta elettronica fra device (Pocket Outlook) e&amp;nbsp; Exchange 2007; ricordo che Exchange 2007 supporta il push dei messaggi verso il device.&lt;/p&gt; &lt;p&gt;Come sempre le sottodirectory wce400 e wce500 contengono i cab per l'installazione reale su device o emulatore in base alla versione del sistema operativo. Ricordo che Windows Mobile 6.0 si basa sempre su Windows CE 5, per precisione sulla 5.2.&lt;/p&gt; &lt;p&gt;System.Data.Entities contiene invece le parti applicative dell'entitiy framework, mentre il provider è contenuto sotto System.Data.SqlServerCe.Entitiy.dll che arriva con l'installazione di Sql Server Compact Edition 3.5.&lt;/p&gt; &lt;p&gt;SQL CE 3.5 arriva con qualche piccola novità per i device e con grandi novità su utilizzato su desktop, Tablet o UMPC.&lt;/p&gt; &lt;p&gt;La directory di installazione sul pc di sviluppo è x:\program files\Microsoft SQL server Compact Edition\v3.5 e si presenta così:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6148/original.aspx" target="_blank"&gt;&lt;img src="http://thinkmobile.it/photos/orcas/images/6148/425x228.aspx"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Come accennato, entity framework viene reso disponibile tramite System.Data.SqlServerCe.Entity, ma solo se utilizzato su PC, Tablet o UMPC: non è quindi disponibile per Windows Mobile.&lt;/p&gt; &lt;p&gt;L'installazione prevede diversi componenti:&lt;/p&gt; &lt;p&gt;1) SSCEVSTools-ENU.msi: installa i componenti design-time in Orcas sotto la classica directory x:\program files\microsoft visual studio 9\Common7\IDE. Questi componenti non devono essere distribuiti&lt;/p&gt; &lt;p&gt;2) SSCERuntime-ENU.msi: installa i componenti di runtime per desktop, tablet e UMPC. Sono indispensabili sia a runtime che a design time. Questo MSI installa anche i nuovi componenti per la versione desktop di SQCE 3.5: Microsoft Synchronization Services for ADO.NET (OCS) e la già citata System.Data.SqlServerCe.Entity.dll.&lt;/p&gt; &lt;p&gt;3) SSCEDeviceRuntime.msi: installa i componenti destinati ai device e emulatori sulla macchina. Questi componenti sono necessari per l'integrazione con VS Orcas anche sulla macchina di sviluppo.&lt;/p&gt; &lt;p&gt;Le novità che abbiamo bollato come minori (rispetto appunto a EntityFramework e OCS) riguardano soprattutto il query processor :&lt;/p&gt; &lt;p&gt;- data type di tipo timestamp&lt;/p&gt; &lt;p&gt;- nested query&lt;/p&gt; &lt;p&gt;- CROSS apply e OUTER APPLY&lt;/p&gt; &lt;p&gt;- CAST&lt;/p&gt; &lt;p&gt;- TOP (finalmente !!!!!) diventa così più semplice paginare i dati per la loro visualizzazione nei minuscoli schermi&lt;/p&gt; &lt;p&gt;Oltre a OCS e Entity Framework, SQL CE 3.5, se utilizzato sul desktop, fornisce la possibilità di rientrare in una transazione creata con la System.Transaction 2.0: in due parole una operazione su SQL CE 3.5 può essere inserita all'interno del TransactionScope.&lt;/p&gt; &lt;p&gt;I Book On Line non sono ancora disponibili.&lt;/p&gt; &lt;p&gt;Abbiamo accennato nei post precedenti come in Visual Studio Orcas sia possibile effettura Unit Testing su device (o emulatore): credo che questa funzionalità, affiancata dal nuovo .NET CF RPM e dal profiler, siano le novità più importanti e utili della nuova versione.&lt;/p&gt; &lt;p&gt;Tra l'latro in Orcas gli strumenti di Unit Testing non sono più all'interno di Team System, ma disponibili nella versione Professional, almeno a quanto ci è dato sapere oggi.&lt;/p&gt; &lt;p&gt;Ecco le maschere di crezione di uno unit test, praticamente identiche (tranne un settaggio) a quanto oggi disponibile in VSTS:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6151/original.aspx" target="_blank"&gt;&lt;img src="http://thinkmobile.it/photos/orcas/images/6151/425x229.aspx"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6153/original.aspx" target="_blank"&gt;&lt;img src="http://thinkmobile.it/photos/orcas/images/6153/425x285.aspx"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Nella seconda immagine, come si può notare, la configurazione degli host prevede il tipo Smart Device con relativa piattaforma e scelta fra device e emulatore. &lt;/p&gt; &lt;p&gt;Se si crea una performance session su uno Unit Test il codice viene fatto girare sul desktop. &lt;/p&gt; &lt;p&gt;Anche senza l'automatismo in VS Orcas, oggi è possibile eseguire unit test su codice mobile, creando un progetto desktop con i sorgenti mobile linkati al suo interno e oppure compilazioni condizionali nel caso in cui il codice faccia uso di dispositivi, tipo lettore di codice a barre ad esempio, non disponibili sul desktop. Fra qualche giorno posso postare un mio articolo, scritto per Infomedia, proprio su questo argomento. La demo allegata all'articolo è già disponibile sul mio sito Think Mobile all'indirizzo &lt;a title="http://thinkmobile.it/files/folders/mmdcii/entry5896.aspx" href="http://thinkmobile.it/files/folders/mmdcii/entry5896.aspx"&gt;http://thinkmobile.it/files/folders/mmdcii/entry5896.aspx&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Il nuovo Device Emulator 3.0 si presenta così:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6149/original.aspx" target="_blank"&gt;&lt;img src="http://thinkmobile.it/photos/orcas/images/6149/350x425.aspx"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;A parte la user interface pressochè identica, è possibile salvare la configurazione degli emulatori con Save As e riconfigurare l'emulatore. Il file di configurazione (.defcfg) è anche molto semplice da modificare a mano per cambiare al volo qualcosa senza ricorre alla user interface e soprattutto per poter scambiare la configurazione degli emulatori fra i membri di un team di sviluppo senza doverla ricreare su ogni PC di sviluppo.  &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href="http://thinkmobile.it/photos/orcas/images/6150/original.aspx" target="_blank"&gt;&lt;img src="http://thinkmobile.it/photos/orcas/images/6150/425x189.aspx"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Dopo la nostra DevCon 2007 proseguiamo con SQL CE 3.5 e soprattutto con LINQ e WCF su mobile.&lt;/p&gt; &lt;p&gt;Alla prossima.&lt;/p&gt;&lt;img src="http://blogs.devleap.com/aggbug.aspx?PostID=17304" width="1" height="1"&gt;</content><author><name>rob</name><uri>http://blogs.devleap.com/members/rob.aspx</uri></author></entry><entry><title>ASP.NET 2.0 Async Techniques </title><link rel="alternate" type="text/html" href="http://blogs.devleap.com/articolidevleap/archive/2007/02/07/asp-net-2-0-async-techniques.aspx" /><id>http://blogs.devleap.com/articolidevleap/archive/2007/02/07/asp-net-2-0-async-techniques.aspx</id><published>2007-02-07T18.55.00Z</published><updated>2007-02-07T18.55.00Z</updated><content type="html">&lt;P&gt;Articolo pubblicato su Computer Programming nel 2006.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Questo articolo, diviso in due parti unite in questo testo, introduce le problematiche di programmazione asincrona (e di conseguenza multithread) in ASP.NET, ripercorrendo passo per passo le modalità disponibili in ASP.NET 1.x per arrivare alle novità della versione 2.0. Il flusso, anche se con meno dettagli per questioni di spazio, ripercorre gli argomenti dei corsi www.devleap.it su ASP.NET 1.x e 2.0 Core. Per ogni demo, l'articolo contiene il codice relativo che potete copiare direttamente; all'indirizzo www.thinkmobile.it:9000/Async ho pubblicato tutti gli esempi funzionanti live in modo che possiate vedere e verificare il tutto su un server Windows 2003 già configurato: a sinistra trovate un menù che porta alle varie pagine riportate in questo articolo.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Quando si parla di programmazione asincrona facciamo riferimento all'esecuzione di operazioni su thread differenti, parallelizzando diverse richieste a risorse remote in modo da annullare il più possibile i tempi di attesa su ciascuna di esse: iniziare un articolo con un frase criptica solitamente incuriosisce il lettore :-)&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Proviamo a spiegarci con alcuni esempi partendo da un client Windows (o mobile) tradizionale per poi spostarci su ASP.NET. Il mio obiettivo è chiarire e semplificare, il più possibile, concetti che esistono da sempre nello sviluppo di applicazioni e calarli piano piano nella realtà web che, come sempre, differisce dallo sviluppo di applicazioni tradizionali. Forniamo esempi molto semplici e facilmente riproducibili. In questo primo articolo ci dilungheremo un po' anche su IIS, Thread Pool e Asynchronous Thread Queue (ATQ) per inquadrare bene la problematica e dare al lettore elementi concreti di valutazione, piuttosto che segnalare solamente le carattestistiche di ASP.NET senza inquadrarle nello scenario complessivo.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Supponiamo di avere un client Windows che deve effettuare due chiamate a web service remoti per ottenere alcune informazioni. Utilizzeremo per praticità un solo web service il cui codice .NET 2.0 è il seguente.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;---- SalesmanManagerWS.asmx ---&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-highlight:yellow;"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;@&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt; &lt;SPAN style="COLOR:maroon;"&gt;WebService&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Language&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="C#"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;CodeBehind&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="~/App_Code/SalesmanManagerWS.cs"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Class&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="SalesmanManagerWS"&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';mso-ansi-language:EN-GB;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';mso-ansi-language:EN-GB;"&gt;--- SalesmanManagerWS.asmx.cs ---&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;using&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt; System;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;using&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt; System.Web;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;using&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt; System.Web.Services;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;using&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt; System.Web.Services.Protocols;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;using&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt; System.Threading;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;[WebService(Namespace = &lt;SPAN style="COLOR:maroon;"&gt;"http://tempuri.org/"&lt;/SPAN&gt;)]&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;public&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt; &lt;SPAN style="COLOR:blue;"&gt;class&lt;/SPAN&gt; SalesmanManagerWS : System.Web.Services.WebService&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;{&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;public&lt;/SPAN&gt; SalesmanManagerWS () {&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;//Uncomment the following line if using designed components &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;//InitializeComponent(); &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;[WebMethod]&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;bool&lt;/SPAN&gt; SalvaAgente(&lt;SPAN style="COLOR:blue;"&gt;string&lt;/SPAN&gt; idAgente, &lt;SPAN style="COLOR:blue;"&gt;string&lt;/SPAN&gt; descrizione) &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:teal;"&gt;Thread&lt;/SPAN&gt;.Sleep(2000);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;try&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;SalesmanManager sm = &lt;SPAN style="COLOR:blue;"&gt;new&lt;/SPAN&gt; SalesmanManager();&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;sm.AggiornaAgente(idAgente, descrizione);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;true&lt;/SPAN&gt;;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;catch&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;false&lt;/SPAN&gt;;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Come si nota, il web service chiama una classe del Business Layer per salvare i dati di un agente nel DB. Per effettuare prove in locale simuliamo un lavoro di due secondi con una Thread.Sleep(2000). In pratica, visto che lavorando in locale si azzerano i tempi di connessione, imponiamo due secondi come tempo di esecuzione del metodo remoto. Nel ricreare l'esempio potete togliere la chiamata al mio Business Layer e adattare il Thread.Sleep ad un valore vicino al vostro scenario.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Costruendo il nostro client .NET, per semplicità, assegneremo al click su un bottone, la chiamata sincrona al metodo SalvaAgente:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;SalesmanManagerWS.&lt;SPAN style="COLOR:teal;"&gt;SalesmanManagerWS&lt;/SPAN&gt; ws = &lt;SPAN style="COLOR:blue;"&gt;new&lt;/SPAN&gt; SalesmanManagerWS.&lt;SPAN style="COLOR:teal;"&gt;SalesmanManagerWS&lt;/SPAN&gt;();&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;bool&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt; ris = ws.SalvaAgente(&lt;SPAN style="COLOR:maroon;"&gt;"robertob"&lt;/SPAN&gt;, &lt;SPAN style="COLOR:maroon;"&gt;"Roberto Brunetti"&lt;/SPAN&gt;);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:14pt;FONT-FAMILY:'Courier New';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Sicuramente la risposta non arriverà prima di due secondi visto che il web service internamente spende due secondi a vuoto. Durante questo tempo il thread che gestisce l'interfaccia utente (la Windows Form) resta bloccato in attesa di una risposta: non è possibile interagire con altri elementi del form e tantomeno con il form stesso (ad esempio minimizzare la finestra oppure spostarla). &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Eseguire una chiama asincrona risolve il problema del blocco del thread principale consentendo all'utente di interagire con il form durante la chiamata. Dalla versione 1.0, il framework .NET mette a disposizione, sulle chiamate ai web service, un pattern che utilizza BeginMetodo e EndMetodo per iniziare una chiamata asincrona senza doversi preoccupare di creare e gestire thread da codice. In pratica la chiamata a BeginSalvaAgente crea, dietro le quinte, un secondo thread per l'esecuzione della richiesta remota. A tale metodo può essere passato un evento che verrà richiamato in automatico al termina della richiesta remota (Callback). Da questo evento è possibile ottenere il risultato della chiamata tramite il metodo EndSalvaAgente. In pratica nel metodo button_click si esegue la chiamata asincrona:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;SalesmanManagerWS.&lt;SPAN style="COLOR:teal;"&gt;SalesmanManagerWS&lt;/SPAN&gt; ws = &lt;SPAN style="COLOR:blue;"&gt;new&lt;/SPAN&gt; SalesmanManagerWS.&lt;SPAN style="COLOR:teal;"&gt;SalesmanManagerWS&lt;/SPAN&gt;();&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:teal;FONT-FAMILY:'Courier New';"&gt;IAsyncResult&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt; ar = ws.BeginSalvaAgente(&lt;SPAN style="COLOR:maroon;"&gt;"robertob"&lt;/SPAN&gt;, &lt;SPAN style="COLOR:maroon;"&gt;"Roberto Brunetti"&lt;/SPAN&gt;, AgenteSalvato, ws);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;definendo poi un event handler per recuperare il risultato al termine della chiamata:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;private&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt; &lt;SPAN style="COLOR:blue;"&gt;void&lt;/SPAN&gt; AgenteSalvato(&lt;SPAN style="COLOR:teal;"&gt;IAsyncResult&lt;/SPAN&gt; ar)&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;SalesmanManagerWS.&lt;SPAN style="COLOR:teal;"&gt;SalesmanManagerWS&lt;/SPAN&gt; ws = (SalesmanManagerWS.&lt;SPAN style="COLOR:teal;"&gt;SalesmanManagerWS&lt;/SPAN&gt;)ar.AsyncState;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;bool&lt;/SPAN&gt; ris = ws.EndSalvaAgente(ar);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;La chiamata impiega sempre un tempo non inferiore ai due secondi, ma il thread principale non viene bloccato durante questa attesa. Non mi dilungo su questi metodi visto che sono presenti nel .NET Framework (e .NET Compact Framework) sino dal febbraio 2002, mese di uscita ufficiale del framework. Abbiamo quindi risolto, senza impazzire con il codice, il primo problema.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Complichiamo, si fa per dire, l'esempio richiamando due web service (nel nostro caso dimostrativo chiameremo sempre lo stesso metodo). Eseguendo due chiamate sincrone è ovvio che il tempo di risposta totale non possa essere inferiore a 4 secondi. Il thread resta bloccato per almeno due secondi per effettuare la prima chiamata e poi per almeno altri due secondi per aspettare la seconda risposta. In questo caso una chiamata (anzi due) asincrona al web service, non solo fa sì che il thread non resti bloccato, ma consente di parallelizzare le due richieste ottenendo un tempo di risposta notevolmente inferiore. Test sulla mia macchina evidenziano che la chiamata sincrona a un web service (a regime) impiega circa 2,016 secondi, la chiamata sincrona a due web service impiegano circa 4,016 secondi. Effettuando chiamate asicrone si ottiene un tempo di riposta di 2,016 per una sola richiesta e di 2,031 secondi per entrambe le richieste.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Facciamo il punto per poi spostarci nel mondo ASP.NET: nel caso di una sola richiesta, con una chiamata asincrona non possiamo migliorare il tempo di risposta in quanto il nostro web service impiega comunque almeno 2 secondi per essere eseguito; con una chiamata asincrona miglioriamo solamente l'interattività dell'utente con il form in quanto la chiamata viene spostata su un thread diverso da quello che gestisce la user interface (e non è poco). Nel caso di due chiamate (o più di due ovviamente) con le chiamate asincrone riusciamo a parallelizzare le richieste da più thread concorrenti (senza dover creare e gestire a mano i thread) abbassando il tempo di risposta totale (sempre che la linea lo permetta). Ad esempio se dobbiamo effettuare 3 richieste che normalmente impiegano rispettivamente 3 secondi, 4 secondi e 6 secondi, nel caso di chiamate sincrone il miglior risultato che possiamo ottenere è superiore ai 13 secondi, con chiamate asincrone possiamo arrivare fino a 6 secondi. Con chiamate sincrone avremo un solo thread in esecuzione, nel caso di chiamate asincrone avremo fino a 3 thread in contemporanea. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;E' bene sottolineare da subito che l'utlizzo di più thread, di per se, peggiora i tempi di esecuzione in quanto carichiamo il sistema con la gestione di più thread che implica operazioni di thread switch; abbiamo però dimostrato come l'utlizzo di queste tecniche sia particolarmente efficace durante l'utilizzo di risorse remote in quanto si possono parallelizzare le richieste e diminuire i tempi morti di attesa nelle risposte.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Il pattern BeginMetodo/EndMetodo è disponibile nel .NET Framework 1.x per le chiamate ai web service (la classe proxy autogenerata da Visual Studio o con WSDL.exe contiene questa coppia di metodi per ogni metodo esposto dal web service), per i metodi esposti da molte classi del namespace System.IO e del namespace System.Net e nella versione 2.0 anche per accedere a SQL Server tramite i metodi della SqlClient. In pratica ovunque si debba lavorare con risorse remote come il file system, le risorse in rete e perchè no anche SQL Server.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Il .NET Framework 2.0 espone anche un nuovo e semplificato pattern per le chiamate asincrone, alternativo a Begin/End, che non richiede la definizione di IAsyncResult/AyncCallback. In pratica la chiamata si riassume nel codice seguente:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;SalesmanManagerWS.&lt;SPAN style="COLOR:teal;"&gt;SalesmanManagerWS&lt;/SPAN&gt; ws = &lt;SPAN style="COLOR:blue;"&gt;new&lt;/SPAN&gt; SalesmanManagerWS.&lt;SPAN style="COLOR:teal;"&gt;SalesmanManagerWS&lt;/SPAN&gt;();&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:'Courier New';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:'Courier New';"&gt;// Nuova riga&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;ws.SalvaAgenteCompleted += &lt;SPAN style="COLOR:blue;"&gt;this&lt;/SPAN&gt;.OnSalvaAgenteCompleted; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;ws.SalvaAgenteAsync(&lt;SPAN style="COLOR:maroon;"&gt;"Robertob"&lt;/SPAN&gt;, &lt;SPAN style="COLOR:maroon;"&gt;"Roberto Brunetti"&lt;/SPAN&gt;);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:'Courier New';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:'Courier New';"&gt;// Non occre definire il delegate (fa lui)&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:'Courier New';"&gt;//IAsyncResult ar = ws.BeginSalvaAgente("robertob", "Roberto Brunetti", AgenteSalvato, ws);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;e l'evento di callback diventa:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;private&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt; &lt;SPAN style="COLOR:blue;"&gt;void&lt;/SPAN&gt; OnSalvaAgenteCompleted(&lt;SPAN style="COLOR:blue;"&gt;object&lt;/SPAN&gt; sender, SalesmanManagerWS.&lt;SPAN style="COLOR:teal;"&gt;SalvaAgenteCompletedEventArgs&lt;/SPAN&gt; e)&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;{&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;// N.B. Typed Result (SalvaAgenteCompletedEventArgs)&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;// Via ar.AsyncState&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;// SalesmanManagerWS.SalesmanManagerWS ws = (SalesmanManagerWS.SalesmanManagerWS)ar.AsyncState;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:'Courier New';"&gt;// bool ris = ws.EndSalvaAgente(ar);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;bool&lt;/SPAN&gt; ris = e.Result;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Da notare come il risultato sia tipizzato, non occorrano cast rispetto alla classe proxy e quanto il codice sia più semplice da leggere rispetto all'esempio iniziale (le righe commentate rappresentano il codice Begin/End); sfortunatamente questo nuovo pattern non è disponibile per tutte le classi che implementano metodi asincroni: ha quindi senso capire e utilizzare anche la sintassi Begin/End in quanto per molte classi (fra cui i vari oggetti SqlClient) occorre ancora lavorare con questo pattern. Creare thread secondari consente anche di eseguire in asincrono operazioni di inizializzazione e start-up di form e applicazioni senza "rubare" tempo prezioso al thread principale durante le attese di risorse remote.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Inquadrate problematiche e soluzioni per un client Windows Form passiamo a ASP.NET che presenta una serie di problematiche diverse: non siamo più lato-client con una interfaccia "mono-user", ma operiamo server-side con diverse richieste in contemporanea. Ad ogni richiesta che arriva via Http viene assegnato un thread che recupera la risorsa da disco e la invia come risposta: questo compito viene assolto da Internet Information Service su macchine Windows. Nel caso in cui la richiesta sia per una risorsa gestita da ASP.NET, IIS tramite la ISAPI Application (o Extension che dir si voglia) ASPNET_ISAPI.DLL, ridirige la richiesta verso&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;il processo ASPNET_WP in IIS 5 o W3WP in IIS 6. Quando il motore di ASP.NET ha completato il suo lavoro, IIS invia la risposta al client che ha richiesto la risorsa. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;B&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';mso-ansi-language:EN-GB;"&gt;IIS Thread Pool e Asynchronous Thread Queue&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Immaginate cosa succederebbe se per ogni richiesta venisse creato un thread diverso: se sul sito arrivano 1.000 richieste concorrenti avremmo 1.000 thread concorrenti nel processo di Internet Information Service, "tutti il lotta fra di loro sullo stesso sistema" per recuperare le risorse e inviarle al client: come abbiamo accennato nella prima parte dell'articolo avere tanti thread significare caricare il processore per gestire il time slice di ogni thread, l'assegnazione delle risorse della macchina al thread in esecuzione e il thread switch per passare da un thread all'altro. Senza dilungarci, in pratica, il costo di gestione dei thread influirebbe in modo pesante sul tempo di esecuzione delle singole richieste. Dall'altra parte non sarebbe possibile processare le richieste con un solo thread in quanto il centisimo utente aspetterebbe il completamento delle 99 richieste precedenti prima di vedere arrivare una risposta. "Scalando" (applicando su scala server &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Wingdings;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:Arial;mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;&lt;SPAN style="mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;J&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;) il ragionamento che abbiamo appena fatto per un client sarebbe molto intelligente sfruttare i tempi morti di ogni richiesta per iniziare a processare una seconda richiesta: ad esempio quando viene recuperata una pagina html o una immagine da disco, durante il tempo di attesa necessario per spostare le testine sul disco e rintracciare la risorsa potremmo dare un po' di tempo CPU ad un'altra richiesta: così facendo, come abbiamo esasperato nel primo esempio del web service che impiega due secondi (e sperando che il nostro disco non ci metta due secondi per recuperare una risorsa :-)) una seconda richiesta può essere portata avanti mentre la prima attende una risorsa. E' importante però che il thread che aspetta l'IO del disco venga recuperato e assegnato ad altre operazioni per evitare appunto la creazione (e il costo di gestione) di troppi thread sul sistema. Inoltre, anche la creazione di un thread ha un costo, così come la sua terminazione: sarebbe bene non creare e uccidere un thread per ogni richiesta altrimenti si richia che il costo di creazione/distruzione appesantisca il sistema. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Da questa idea, sin dalle prime versioni di IIS, così come per molti application server, si è pensato alla creazione di un thread pool e a una coda di richieste: mi spiego meglio. Un thread pool è un insieme finito di thread che viene creato in un processo. Partiamo da un caso con pochissime richieste per inquadrare il tutto: nel momento in cui arriva la prima richiesta viene creato un thread T1, nel momento in cui arriva la seconda richiesta viene creato un secondo thread T2; nel momento in cui arriva la terza richiesta è probabile che la prima abbia già terminato l suo lavoro: il thread T1, al termine del lavoro sulla prima richiesta, anzichè essere "ucciso" viene inserito nel pool di thread e reso quindi disponibile alla richiesta numero 3. Arriva la richiesta numero 4: se ci sono thread disponibili nel thread pool la richiesta viene assegnata ad un thread esistente, altrimenti viene creato un nuovo thread T3. Tutto questo fino al limite dei thread configurabile per il thread pool. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Pensate che in IIS 4.0 il numero dei thread del thread pool era impostato per default a 10 !!! In pratica IIS 4 non può processare che 10 richieste contemporanee: prima di spaventarsi ripercorriamo un attimo il ragionamento: occorre sfruttare al massimo i tempi morti durante l'esecuzione di una richiesta/risposta http, come ad esempio l'accesso al disco o a una risorsa in rete (non stiamo ancora parlando di applicazioni ASP.NET) per evitare che il numero di thread cresca a dismisura e causi problemi di performance. Visto che le richieste in IIS prevedono nella maggioranza dei casi l'accesso a risorse su disco (pagine html, immagini e così via) e questo accesso sia solitamente velocissimo (anche per la cache dei file più acceduti) avere un numero di thread così basso consente di mantenere "leggero" il sistema pur fornendo un ottimo throughput. Il rapporto, sempre parlando in media, è circa 100:10 (notare che non è 10:1); questo rapporto indica che per 100 richieste che arrivano via Http sono necessari una decina di thread per soddisfare comunque tutte e cento le richieste per risorse normali; per normali intendo pagine di contenuti, immagini, css; se il server deve fare strema video o scaricare immagini da 100 MB cadauna ovviamente il ragionamento 100:10 dovrebbe essere rivisto. Il punto chiave di questi esempi non sono i numeri di per se, ma la relatività della teoria: voglio dire che il ragionamento non cambia se su un sito con risorse pesanti il rapporto debba essere 100:20.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Supponiamo di avere i 10 thread del thread pool impegnati da richieste esistenti: cosa succede alla undicesima richiesta ? Con la teoria esposta fino a adesso dovremmo rispondere: al client arriverà una risposta "Server Too Busy". Ovviamente non è così altrimenti potremmo affermare che IIS non è un gran che come web server &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Wingdings;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:Arial;mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;&lt;SPAN style="mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;J&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt; Le richieste, prima di essere processate, vengono inserite in una coda e prelevate dai vari thread disponibili nel thread pool per essere eseguite. Solo al riempimento di tale coda il server risponderà "Server Too Busy". Si utilizza quindi una tecnica (che ha senso utilizzare nelle nostre applicazioni per scenari simili tramite servizi di accodamento custom o tramite MSMQ) molto intelligente: si accodano le richieste, fino ad un certo limite, e si processano in parallelo solo un numero finito di richieste (con i thread del thread pool) per cercare di ottimizzare il più possibile il bilanciamento fra richieste processabili dal sistema e affaticamento del sistema stesso. Ovviamente questi limiti (thread pool e numero di richieste accodabili, così come altri parametri relativi) possono essere adattati al proprio scenario. Non abbiamo lo spazio per una trattazione esaustiva di questi parametri anche perchè dobbiamo arrivare al cuore dell'articolo ovvero ASP.NET e le pagine asincrone: ricordatevi però sempre che aumentare in modo indiscriminato questi parametri, a prima vista molto bassi, non è una buona idea. Ad esempio superare il valore 60-80 per i thread del thread pool non è quasi mai una buona idea. Vi rimando al Resource Kit di IIS 6.0 per una trattazione approfondita di questi parametri e le tecniche di stress test per verificare il valore ottimale.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;B&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;ASP.NET Thread Pool&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Se la richiesta che ha raggiunto IIS è destinata ad una risorsa ASP.NET, questa viene inviata al motore di ASP.NET da ASPNET_ISAPI.dll e, a questo punto senza sorpresa, vi comunico che anche ASP.NET ha una coda per gestire le richieste prima di essere assegnate ai thread di un thread pool interno al processo di ASP.NET (o i processi di ASP.NET nel caso di IIS 6). &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Anche ASP.NET ragiona quindi con la teoria che abbiamo appena esposto: appena arriva una richiesta, questa viene accodata; viene poi recuperato un thread del thread pool per processare la richiesta. Anche in questo caso il riempimento della coda fa sì che venga rifiutata la richiesta. Per default ASP.NET ha un thread pool di 25 thread (alcuni devono però essere usati dal motore per operazioni di routine come controllo della cache, ricompilazione, gestione delle session...anche se sapete da sempre che non andrebbero usate !!!). &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Non dovrebbe sembrare strano, a questo punto, che il valore di default del thread pool di IIS sia più basso rispetto a quello di ASP.NET: la richiesta arriva a IIS e viene accodata, appena si rende disponibile un thread si inizia a processare la richiesta che viene passata a ASP.NET. Il thread in IIS può essere rimesso immediatamente nel pool e reso disponibile per altre richieste (HTML, immagini e così via) mentre ASP.NET processa la richiesta, sicuramente più complessa, rispetto a prelevare un semplice file da disco. Se arriva una seconda richiesta per ASP.NET, magari è lo stesso thread che ha inviato la prima richiesta ad inviare anche la seconda richiesta. Quando le risposte da parte di ASP.NET sono pronte viene recuperato un thread libero nel thread pool di IIS per mandare la risposta al client. Ottimo no ?&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;B&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;ASP.NET Sync/Async&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;A questo punto diventa chiara la seguente affermazione: occorre occupare per meno tempo possibile i thread del thread pool durante l'esecuzione di una richiesta in modo da renderli disponibili alle richieste entranti. Come fare ? Se una elaborazione occupa tempo CPU (ad esempio per fare dei calcoli) difficilmente possiamo fare a meno di occupare un thread, ma se la richiesta deve accedere a risorse (disco, rete, web service, database) possiamo liberare il prima possibile il thread (effettuando una chiamata asincrona) in modo da farlo lavorare su un'altra richiesta. Predisponiamo il terreno anche in ASP.NET per effttuare i vari test che proseguiremo in un prossimo articolo dove andremo in dettaglio su ASP.NET 1.x e ASP.NET 2.0 per capire le differenze e le nuove facilitazioni.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Per testare il tutto ho preparato la seguente Master Page che visualizza (menu per le varie demo a parte) un trace delle operazioni e il sorgente della pagina richiesta. In pratica la master page espone un metodo, richiamabile dalle varie pagine delle demo, AddTraceMessage che visualizza il tempo dall'inizio della richiesta, il numero di thread occupati e liberi del thread pool e la stringa di trace. Questa la mia master page:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:14pt;FONT-FAMILY:'Arial','sans-serif';"&gt;--- Master.Master ---&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-highlight:yellow;"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;@&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;Language&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="C#"&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-highlight:yellow;"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;@&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt; &lt;SPAN style="COLOR:maroon;"&gt;Import&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Namespace&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="System.IO"&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-highlight:yellow;"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;@&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt; &lt;SPAN style="COLOR:maroon;"&gt;Import&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Namespace&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="System.Threading"&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&amp;lt;!&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:maroon;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;DOCTYPE&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt; &lt;SPAN style="COLOR:red;"&gt;html&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;PUBLIC&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;"-//W3C//DTD XHTML 1.1//EN"&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:FR;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:maroon;FONT-FAMILY:'Courier New';mso-ansi-language:FR;"&gt;script&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:FR;"&gt; &lt;SPAN style="COLOR:red;"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="server"&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:FR;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:FR;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;void Page_Init()&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:FR;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:FR;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;AddTraceMessage("Page_Init");&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:FR;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;Page.PreRenderComplete += new EventHandler(this.PagePreRenderComplete);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;void PagePreRenderComplete(Object source, EventArgs e)&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;AddTraceMessage("PreRenderComplete");&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;using (TextReader r = new StreamReader(Request.PhysicalPath))&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;SourceLabel.Text = HttpUtility.HtmlEncode(r.ReadToEnd());&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;StringBuilder _trace = new StringBuilder();&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;DateTime _pageStartTime = DateTime.Now;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;public void AddTraceMessage(string message)&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;double t = (DateTime.Now - _pageStartTime).TotalSeconds;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Int32 i;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Int32 totalWorkerThreads;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;// Numero massimo di thread del thread pool&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ThreadPool.GetMaxThreads(out totalWorkerThreads, out i);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Int32 availableWorkerThreads;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ThreadPool.GetAvailableThreads(out availableWorkerThreads, out i);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;// Thread di tutto il processo&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Int32 totalThreadCounts = System.Diagnostics.Process.GetCurrentProcess().Threads.Count;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;lock (_trace)&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;_trace.AppendFormat("[{0:000}] {1:00.000} - {5} - [{3}/{4}/{6}] -- {2}\r\n",&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;Thread.CurrentThread.GetHashCode(), t, "Thread " + AppDomain.GetCurrentThreadId() + " " + message,&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;totalWorkerThreads - availableWorkerThreads, totalWorkerThreads, &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Thread.CurrentThread.IsThreadPoolThread ? "TP" : "!TP",&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;totalThreadCounts);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:maroon;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;script&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:maroon;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;html&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt; &lt;SPAN style="COLOR:red;"&gt;xmlns&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="http://www.w3.org/1999/xhtml"&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:maroon;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;head&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt; &lt;SPAN style="COLOR:red;"&gt;id&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="Head1"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="server"&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;title&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;gt;&lt;/SPAN&gt;Sample Page&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;title&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:maroon;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;head&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:maroon;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;body&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;form&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;id&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="form"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="server"&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;table&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;tr&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;td&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;valign&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="top"&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;p&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;asp&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;SiteMapPath&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;ID&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="SiteMapPathNode"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="server"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Font-Names&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="Verdana"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;PathSeparator&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;=" : "&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;EnableViewState&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="False"&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;PathSeparatorStyle&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Font-Bold&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="True"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;ForeColor&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="#990000"&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;CurrentNodeStyle&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;ForeColor&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="#333333"&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;NodeStyle&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Font-Bold&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="True"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;ForeColor&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="#FF8000"&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;RootNodeStyle&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Font-Bold&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="True"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;ForeColor&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="#990000"&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;asp&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;SiteMapPath&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;asp&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;SiteMapDataSource&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;ID&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="SiteMapDS"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="server"&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;p&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;p&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;asp&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;TreeView&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;ID&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="SiteTreeView"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="server"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;DataSourceID&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="SiteMapDS"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;ImageSet&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="Simple"&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;Font-Names&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="Verdana"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Font-Size&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="0.9em"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;EnableViewState&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="False"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;NodeWrap&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="True"&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;SelectedNodeStyle&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;ForeColor&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="#990000"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Font-Bold&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="True"&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;NodeStyle&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;VerticalPadding&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="2px"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;ForeColor&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="Black"&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;HoverNodeStyle&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Font-Underline&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="True"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;ForeColor&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="#5555DD"&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;ParentNodeStyle&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;asp&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;TreeView&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;p&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;td&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;td&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;valign&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="top"&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;asp&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;Label&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;ID&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="Label1"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="server"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Text&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="Page Trace:"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Font-Bold&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="True"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Font-Names&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="Verdana"&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;Font-Size&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="0.8em"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;ForeColor&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="Maroon"&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;pre&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="BACKGROUND:yellow;mso-highlight:yellow;"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;=&lt;/SPAN&gt; _trace.ToString() &lt;SPAN style="BACKGROUND:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;pre&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;hr&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;asp&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;Label&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;ID&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="Label2"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="server"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Text&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="Page Source:"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Font-Bold&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="True"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Font-Names&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="Verdana"&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;Font-Size&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="0.8em"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;ForeColor&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="Maroon"&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;pre&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;asp&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;Label&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;ID&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="SourceLabel"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="server"&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;/&amp;gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;pre&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;td&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;tr&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;table&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;form&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:maroon;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;body&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:maroon;FONT-FAMILY:'Courier New';"&gt;html&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Come si può notare, viene intercettato il Page_Init per inserire un messaggio iniziale nel trace e abbonarsi all'evento PreRenderComplete nel cui event handler viene letto il sorgente della pagina e valorizzata la label che lo visualizza. Il PreRenderComplete è un punto importante nell'esecuzione di pagine asincrone e lo analizzeremo in dettaglio nel prossimo articolo.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;A questo punto possiamo costruire la prima pagina (referenziando la master page) che esegue una chiamata sincrona al nostro famoso (e lento) web service che impiega 2 secondi per essere eseguito.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:5pt 0cm;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:14pt;COLOR:black;FONT-FAMILY:'Arial','sans-serif';"&gt;--- &lt;/SPAN&gt;&lt;SPAN style="COLOR:black;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;A href="http://blogs.devleap.com/Async/01ChiamaUnWS.aspx"&gt;&lt;SPAN style="FONT-SIZE:14pt;COLOR:black;TEXT-DECORATION:none;text-underline:none;"&gt;Sync Page Chiama 1 Web Service&lt;/SPAN&gt;&lt;/A&gt;&lt;FONT size=3&gt; &lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:14pt;COLOR:black;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/SPAN&gt;---&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-highlight:yellow;"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;@&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt; &lt;SPAN style="COLOR:maroon;"&gt;Page&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Language&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="C#"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;AutoEventWireup&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="true"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;MasterPageFile&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="~/MasterPage.master"&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-highlight:yellow;"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;@&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt; &lt;SPAN style="COLOR:maroon;"&gt;MasterType&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;VirtualPath&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="~/MasterPage.master"&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-highlight:yellow;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:maroon;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;script&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt; &lt;SPAN style="COLOR:red;"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="server"&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;void&lt;/SPAN&gt; Page_Load() {&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Master.AddTraceMessage(&lt;SPAN style="COLOR:maroon;"&gt;"SalvaAgente 1.0 Sync"&lt;/SPAN&gt;);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;SalesmanManagerWS.&lt;SPAN style="COLOR:teal;"&gt;SalesmanManagerWS&lt;/SPAN&gt; ws = &lt;SPAN style="COLOR:blue;"&gt;new&lt;/SPAN&gt; SalesmanManagerWS.&lt;SPAN style="COLOR:teal;"&gt;SalesmanManagerWS&lt;/SPAN&gt;();&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;bool&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt; ris = ws.SalvaAgente(&lt;SPAN style="COLOR:maroon;"&gt;"robertob"&lt;/SPAN&gt;, &lt;SPAN style="COLOR:maroon;"&gt;"RobertoBrunetti"&lt;/SPAN&gt;);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Master.AddTraceMessage(&lt;SPAN style="COLOR:maroon;"&gt;"SalvaAgente 1.0 Finito"&lt;/SPAN&gt;);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Master.AddTraceMessage(&lt;SPAN style="COLOR:maroon;"&gt;"Risultato "&lt;/SPAN&gt; + ris.ToString());&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:maroon;FONT-FAMILY:'Courier New';"&gt;script&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Il codice non è diverso da quanto facevamo nel click del bottone della Windows Form all'inizio dell'articolo. Viene istanziato il web service e invocato il metodo SalvaAgente. Il resto del codice ci consente di inserire messaggi nel trace, che come abbiamo visto nella master page, visualizza informazioni importanti sui thread. Ecco il risultato della esecuzione (depurato del sorgente e del menu per questioni di spazio):&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;tab-stops:0cm 47.95pt 95.9pt 143.85pt 191.8pt 239.75pt 287.7pt 335.65pt 383.6pt 431.55pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;[007] 00,000 - TP - [1/100/25] -- Thread 2264 Page_Init&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;tab-stops:0cm 47.95pt 95.9pt 143.85pt 191.8pt 239.75pt 287.7pt 335.65pt 383.6pt 431.55pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;[007] 00,000 - TP - [1/100/25] -- Thread 2264 SalvaAgente 1.0 Sync&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;tab-stops:0cm 47.95pt 95.9pt 143.85pt 191.8pt 239.75pt 287.7pt 335.65pt 383.6pt 431.55pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;[007] 02,016 - TP - [1/100/27] -- Thread 2264 SalvaAgente 1.0 Finito&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;tab-stops:0cm 47.95pt 95.9pt 143.85pt 191.8pt 239.75pt 287.7pt 335.65pt 383.6pt 431.55pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;[007] 02,016 - TP - [1/100/27] -- Thread 2264 Risultato True&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;tab-stops:0cm 47.95pt 95.9pt 143.85pt 191.8pt 239.75pt 287.7pt 335.65pt 383.6pt 431.55pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;[007] 02,016 - TP - [1/100/27] -- Thread 2264 PreRenderComplete&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:14pt;FONT-FAMILY:'Courier New';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Il trace ci mostra, in prima battuta, che la pagina ha richiesto 2,016 secondi per essere eseguita: ricordatevi che sotto i due secondi non possono scendere in quanto il metodo del nostro web service impiega almeno due secondi per essere eseguito. Per semplicità ho pubblicato tutti gli esempi all’indirizzo http://thinkmobile.it:9000/async: visto che la master page visualizza il sorgente non avete bisogno di riscriverli…copiateli direttamente.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Il trace mostra 5 messaggi di trace, che grazie al metodo esposto dalla master page visualizza, per ogni chiamata, l'hash code del thread, il tempo di esecuzione dall'inizio della richiesta, TP nel caso in cui si stia utilizzando un thread del thread pool, l'id del thread e il messaggio passato come parametro al metodo. Page_Init e PreRenderComplete vengono aggiunti dal codice della master page. I valori fra parentesi quadre [X/XXX/XX] rappresentano rispettivamente il numero dei thread impegnati nel thread pool, il numero massimo di thread ospitabili e il numero di thread liberi a disposizione.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Come si può notare per eseguire questa pagina che effettua la chiamata sincrona al metodo del web service viene impiegato un solo thread (il 2264) e il tempo fra la chiamata (SalvaAgente 1.0 Sync) e la risposta (SalvaAgente 1.0 Finito) è di poco superiore ai due secondi: questo indica, come abbiamo avuto modo di dire più volte, che il thread aspetta l'intero ciclo della chiamata al metodo. In pratica con una chiamata sincrona stiamo impegnando un solo thread del thread pool per tutta la durata della richiesta; se il thread pool dispone di 20 thread significa che potremmo effettuare fino a 20 richieste in contemporanea e che la ventunesima richiesta aspetterebbe in coda circa due secondi per essere iniziata a processare. Se la coda può ospitare al massimo 100 richieste significa che prima di arrivare a processare la 81 richiesta occorre aspettare 4 trance da 2 secondi (8 secondi almeno). Inoltre la coda si libera di 20 posti dopo almeno due secondi: in pratica a regime possiamo accettare massimo 20 richieste ogni 2 secondi (supponendo sempre che le richieste arrivino nello stesso istante).&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Proviamo a chiamare due web service in modo sincrono:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:14pt;COLOR:black;FONT-FAMILY:'Arial','sans-serif';"&gt;--- &lt;/SPAN&gt;&lt;SPAN style="COLOR:black;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;A href="http://blogs.devleap.com/Async/01ChiamaUnWS.aspx"&gt;&lt;SPAN style="FONT-SIZE:14pt;COLOR:black;TEXT-DECORATION:none;text-underline:none;"&gt;Sync Page Chiama 2 Web Service&lt;/SPAN&gt;&lt;/A&gt;&lt;FONT size=3&gt; &lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:14pt;COLOR:black;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/SPAN&gt;---&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-highlight:yellow;"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;@&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt; &lt;SPAN style="COLOR:maroon;"&gt;Page&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Language&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="C#"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;AutoEventWireup&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="true"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;MasterPageFile&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="~/MasterPage.master"&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-highlight:yellow;"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;@&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt; &lt;SPAN style="COLOR:maroon;"&gt;MasterType&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;VirtualPath&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="~/MasterPage.master"&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-highlight:yellow;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:maroon;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;script&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt; &lt;SPAN style="COLOR:red;"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="server"&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;void Page_Load() {&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Master.AddTraceMessage("SalvaAgente 1.0 Sync");&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;SalesmanManagerWS.SalesmanManagerWS ws = new SalesmanManagerWS.SalesmanManagerWS();&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;bool ris = ws.SalvaAgente("robertob", "RobertoBrunetti");&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Master.AddTraceMessage("SalvaAgente 1.0 Finito");&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Master.AddTraceMessage("Risultato 1 " + ris.ToString());&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;SalesmanManagerWS.SalesmanManagerWS ws2 = new SalesmanManagerWS.SalesmanManagerWS();&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;ris = ws2.SalvaAgente("paolopi", "PaoloPialorsi");&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Master.AddTraceMessage("SalvaAgente 1.0 Finito"); &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Master.AddTraceMessage("Risultato 2 " + ris.ToString());&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:maroon;FONT-FAMILY:'Courier New';"&gt;script&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Ed ecco il risultato:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;tab-stops:0cm 47.95pt 95.9pt 143.85pt 191.8pt 239.75pt 287.7pt 335.65pt 383.6pt 431.55pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;[001] 00,000 - TP - [1/100/22] -- Thread 3292 Page_Init&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;tab-stops:0cm 47.95pt 95.9pt 143.85pt 191.8pt 239.75pt 287.7pt 335.65pt 383.6pt 431.55pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;[001] 00,000 - TP - [1/100/22] -- Thread 3292 SalvaAgente 1.0 Sync&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;tab-stops:0cm 47.95pt 95.9pt 143.85pt 191.8pt 239.75pt 287.7pt 335.65pt 383.6pt 431.55pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;[001] 02,547 - TP - [1/100/24] -- Thread 3292 SalvaAgente 1.0 Finito&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;tab-stops:0cm 47.95pt 95.9pt 143.85pt 191.8pt 239.75pt 287.7pt 335.65pt 383.6pt 431.55pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;[001] 02,563 - TP - [1/100/24] -- Thread 3292 Risultato 1 True&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;tab-stops:0cm 47.95pt 95.9pt 143.85pt 191.8pt 239.75pt 287.7pt 335.65pt 383.6pt 431.55pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;[001] 04,578 - TP - [1/100/24] -- Thread 3292 SalvaAgente 1.0 Finito&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;tab-stops:0cm 47.95pt 95.9pt 143.85pt 191.8pt 239.75pt 287.7pt 335.65pt 383.6pt 431.55pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;[001] 04,578 - TP - [1/100/24] -- Thread 3292 Risultato 2 True&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;tab-stops:0cm 47.95pt 95.9pt 143.85pt 191.8pt 239.75pt 287.7pt 335.65pt 383.6pt 431.55pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;[001] 04,578 - TP - [1/100/24] -- Thread 3292 PreRenderComplete&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Anche in questo caso stiamo impegnando un solo thread (il 3292) per l'intera esecuzione della pagina che giustamente dura non meno di 4 secondi (4,578 in questo caso) perchè le due richieste ai due web service sono sequenziali e sincrone e non consentono di parallelizzare le due richieste. Ovviamente abbiamo peggiorato l'esecuzione in quanto adesso ogni richiesta impiega non meno di 4 secondi quindi possiamo accettare un massimo di 20 richieste ogni 4,5 secondi circa.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;B&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Stress (ma non troppo) Test&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Mettendo il sito sotto stress rispetto ad un tempo di risposta di 2,2 secondi circa per la chiamata singola, otteniamo un tempo medio di risposta di 16,3 secondi e varie risposte Server Too Busy per il problema accennato: il dramma però sta nel fatto che il processore della macchina è al 24% di utilizzo; in pratica i tempi di risposta diventano inaccettabili anche con pochi client su una macchina che non è carica: il processore passa la maggior parte del tempo ad aspettare le risposte remote e non viene sfruttato come potrebbe. Mettere un processore più potente per cercare di velocizzare l'applicazione sarebbe l'errore più grande che potremmo fare, in quanto il collo di bottiglia non è il processore, ma il tempo di attesa sincrono della nostra banalissima applicazione. Se portate questo esempio nel mondo reale dove una pagina di un portale fa una decina di chiamate remote a web service otteniamo una situazione catastrofica anche con 20 utenti collegati e un hardware da decine di migliaia di euro.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Dobbiamo migliorare i tempi di attesa e quindi sfruttare meglio la CPU. La soluzione però non è effettuare chiamate asincrone di per se. Vediamo il perchè con un esempio che purtroppo viene raccomandato da molti come soluzione al problema appena citato. Prima di implementarlo aspettate di vedere i risultati e leggere il prossimo articolo dove cercherò di spiegare il motivo per cui modificare solamente le chiamate sincrone in asincrone sia più distruttivo. Il motivo che scopriremo è che ASP.NET 1.x esegue le pagine in modo sincrono e questo comportamento è il default anche per ASP.NET 2.0. Andiamo per gradi.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Proviamo quindi a iniziare con il pattern BeginMetodo a eseguire la chiamata in asincrono. Ecco il codice:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:14pt;COLOR:black;FONT-FAMILY:'Arial','sans-serif';"&gt;--- &lt;/SPAN&gt;&lt;SPAN style="COLOR:black;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;A href="http://blogs.devleap.com/Async/01ChiamaUnWS.aspx"&gt;&lt;SPAN style="FONT-SIZE:14pt;COLOR:black;TEXT-DECORATION:none;text-underline:none;"&gt;Sync Page Chiama 1 Web Service&lt;/SPAN&gt;&lt;/A&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:14pt;COLOR:black;FONT-FAMILY:'Arial','sans-serif';"&gt; BeginXXX &lt;/SPAN&gt;&lt;SPAN style="COLOR:black;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&lt;FONT size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:14pt;COLOR:black;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/SPAN&gt;---&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-highlight:yellow;"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;@&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt; &lt;SPAN style="COLOR:maroon;"&gt;Page&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Language&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="C#"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;AutoEventWireup&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="true"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;MasterPageFile&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="~/MasterPage.master"&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-highlight:yellow;"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;@&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt; &lt;SPAN style="COLOR:maroon;"&gt;MasterType&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;VirtualPath&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="~/MasterPage.master"&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-highlight:yellow;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:maroon;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;script&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt; &lt;SPAN style="COLOR:red;"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="server"&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;void Page_Load() {&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Master.AddTraceMessage("SalvaAgente 1.0 Begin");&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;SalesmanManagerWS.SalesmanManagerWS ws = new SalesmanManagerWS.SalesmanManagerWS();&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;IAsyncResult ar = ws.BeginSalvaAgente("robertob", "RobertoBrunetti", AgenteSalvato, ws);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Master.AddTraceMessage("SalvaAgente 1.0 Fine Chiamata");&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;// Occorre aspettare la fine&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ar.AsyncWaitHandle.WaitOne();&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;private void AgenteSalvato(IAsyncResult ar)&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Master.AddTraceMessage("SalvaAgente 1.0 End");&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;SalesmanManagerWS.SalesmanManagerWS ws = (SalesmanManagerWS.SalesmanManagerWS)ar.AsyncState;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;bool ris = ws.EndSalvaAgente(ar);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;Master.AddTraceMessage("Risultato " + ris.ToString());&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:maroon;FONT-FAMILY:'Courier New';"&gt;script&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Prima di vedere i risultati e fare le dovute considerazioni spendiamo un attimo sulla chiamata a ar.AsyncWaitHandle.WaitOne() che non era presente nel primo esempio asincrono su una Windows Form: questa riga serve per evitare che l'esecuzione della pagina finisca (ed è molto probabile per non dire certo in questo semplice esempio) prima che la chiamata asincrona termini. In pratica si imposta un WaitHandle per segnalare l'attesa sulla chiusura della chiamata asincrona: senza questa istruzione la chiamata asincrona verrebbe comunque completata ma non potremmo visualizzare nessun risultato al client in quanto la risposta sarebbe già stata chiusa da ASP.NET.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Chiarito il concetto vediamo i risultati:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;tab-stops:0cm 47.95pt 95.9pt 143.85pt 191.8pt 239.75pt 287.7pt 335.65pt 383.6pt 431.55pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;[007] 00,000 - TP - [1/100/27] -- Thread 2264 Page_Init&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;tab-stops:0cm 47.95pt 95.9pt 143.85pt 191.8pt 239.75pt 287.7pt 335.65pt 383.6pt 431.55pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;[007] 00,000 - TP - [1/100/27] -- Thread 2264 SalvaAgente 1.0 Begin&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;tab-stops:0cm 47.95pt 95.9pt 143.85pt 191.8pt 239.75pt 287.7pt 335.65pt 383.6pt 431.55pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;[007] 00,000 - TP - [1/100/27] -- Thread 2264 SalvaAgente 1.0 Finito&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;tab-stops:0cm 47.95pt 95.9pt 143.85pt 191.8pt 239.75pt 287.7pt 335.65pt 383.6pt 431.55pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;[005] 02,016 - TP - [1/100/33] -- Thread 2692 SalvaAgente 1.0 End&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;tab-stops:0cm 47.95pt 95.9pt 143.85pt 191.8pt 239.75pt 287.7pt 335.65pt 383.6pt 431.55pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;[005] 02,016 - TP - [1/100/33] -- Thread 2692 Risultato True&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;tab-stops:0cm 47.95pt 95.9pt 143.85pt 191.8pt 239.75pt 287.7pt 335.65pt 383.6pt 431.55pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;[007] 02,016 - TP - [1/100/33] -- Thread 2264 PreRenderComplete&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';mso-ansi-language:EN-GB;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Non ci discostiamo molto come tempi di esecuzione dall'esempio sincrono ed è normale visto che la chiamata comunque impiega due secondi ma come si nota dal trace entra in gioco un secondo thread (il 2692 rispetto al 2264) per la visualizzazione del risultato. Proviamo con due chiamate asincrone:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:14pt;COLOR:black;FONT-FAMILY:'Arial','sans-serif';"&gt;--- &lt;/SPAN&gt;&lt;SPAN style="COLOR:black;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;A href="http://blogs.devleap.com/Async/01ChiamaUnWS.aspx"&gt;&lt;SPAN style="FONT-SIZE:14pt;COLOR:black;TEXT-DECORATION:none;text-underline:none;"&gt;Sync Page Chiama 2 Web Service&lt;/SPAN&gt;&lt;/A&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:14pt;COLOR:black;FONT-FAMILY:'Arial','sans-serif';"&gt; BeginXXX &lt;/SPAN&gt;&lt;SPAN style="COLOR:black;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&lt;FONT size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:14pt;COLOR:black;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/SPAN&gt;---&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-highlight:yellow;"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;@&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt; &lt;SPAN style="COLOR:maroon;"&gt;Page&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Language&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="C#"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;AutoEventWireup&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="true"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;MasterPageFile&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="~/MasterPage.master"&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-highlight:yellow;"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;@&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt; &lt;SPAN style="COLOR:maroon;"&gt;MasterType&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;VirtualPath&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="~/MasterPage.master"&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-highlight:yellow;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:maroon;FONT-FAMILY:'Courier New';"&gt;script&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt; &lt;SPAN style="COLOR:red;"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="server"&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;void&lt;/SPAN&gt; Page_Load() {&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Master.AddTraceMessage(&lt;SPAN style="COLOR:maroon;"&gt;"SalvaAgente 1.0 Begin"&lt;/SPAN&gt;);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;SalesmanManagerWS.&lt;SPAN style="COLOR:teal;"&gt;SalesmanManagerWS&lt;/SPAN&gt; ws = &lt;SPAN style="COLOR:blue;"&gt;new&lt;/SPAN&gt; SalesmanManagerWS.&lt;SPAN style="COLOR:teal;"&gt;SalesmanManagerWS&lt;/SPAN&gt;();&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:teal;"&gt;IAsyncResult&lt;/SPAN&gt; ar = ws.BeginSalvaAgente(&lt;SPAN style="COLOR:maroon;"&gt;"robertob"&lt;/SPAN&gt;, &lt;SPAN style="COLOR:maroon;"&gt;"RobertoBrunetti"&lt;/SPAN&gt;, AgenteSalvato, ws);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Master.AddTraceMessage(&lt;SPAN style="COLOR:maroon;"&gt;"SalvaAgente 1.0 Fine Chiamata"&lt;/SPAN&gt;);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Master.AddTraceMessage(&lt;SPAN style="COLOR:maroon;"&gt;"SalvaAgente 1.0 Begin"&lt;/SPAN&gt;);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;SalesmanManagerWS.&lt;SPAN style="COLOR:teal;"&gt;SalesmanManagerWS&lt;/SPAN&gt; ws2 = &lt;SPAN style="COLOR:blue;"&gt;new&lt;/SPAN&gt; SalesmanManagerWS.&lt;SPAN style="COLOR:teal;"&gt;SalesmanManagerWS&lt;/SPAN&gt;();&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:teal;"&gt;IAsyncResult&lt;/SPAN&gt; ar2 = ws2.BeginSalvaAgente(&lt;SPAN style="COLOR:maroon;"&gt;"robertob"&lt;/SPAN&gt;, &lt;SPAN style="COLOR:maroon;"&gt;"RobertoBrunetti"&lt;/SPAN&gt;, AgenteSalvato, ws);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Master.AddTraceMessage(&lt;SPAN style="COLOR:maroon;"&gt;"SalvaAgente 1.0 Fine Chiamata"&lt;/SPAN&gt;);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;// Occorre in qualche modo aspettare gli Endxxx prima di abbandonare la pagina&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;// Tip: Se possibile fare prima la Wait sul comando più veloce (più veloce in Begin e in End)&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;//&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Così intanto il secondo va avanti&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ar.AsyncWaitHandle.WaitOne();&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ar2.AsyncWaitHandle.WaitOne();&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;void&lt;/SPAN&gt; AgenteSalvato(&lt;SPAN style="COLOR:teal;"&gt;IAsyncResult&lt;/SPAN&gt; ar)&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Master.AddTraceMessage(&lt;SPAN style="COLOR:maroon;"&gt;"SalvaAgente 1.0 End"&lt;/SPAN&gt;);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;SalesmanManagerWS.&lt;SPAN style="COLOR:teal;"&gt;SalesmanManagerWS&lt;/SPAN&gt; ws = (SalesmanManagerWS.&lt;SPAN style="COLOR:teal;"&gt;SalesmanManagerWS&lt;/SPAN&gt;)ar.AsyncState;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;bool&lt;/SPAN&gt; ris = ws.EndSalvaAgente(ar);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Master.AddTraceMessage(&lt;SPAN style="COLOR:maroon;"&gt;"Risultato "&lt;/SPAN&gt; + ris.ToString());&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:maroon;FONT-FAMILY:'Courier New';"&gt;script&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Ecco il risultato:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;[007] 00,000 - TP - [1/100/27] -- Thread 2264 Page_Init&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;[007] 00,016 - TP - [1/100/27] -- Thread 2264 SalvaAgente 1.0 Begin&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;[007] 00,016 - TP - [1/100/29] -- Thread 2264 SalvaAgente 1.0 Finito&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;[007] 00,016 - TP - [1/100/29] -- Thread 2264 SalvaAgente 1.0 Begin&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;[007] 00,016 - TP - [1/100/29] -- Thread 2264 SalvaAgente 1.0 Finito&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;[017] 02,203 - TP - [2/100/30] -- Thread 2792 SalvaAgente 1.0 End&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;[017] 02,203 - TP - [2/100/30] -- Thread 2792 Risultato True&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;[017] 02,703 - TP - [1/100/30] -- Thread 2792 SalvaAgente 1.0 End&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;"&gt;[017] 02,703 - TP - [1/100/30] -- Thread 2792 Risultato True&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';"&gt;[007] 02,703 - TP - [1/100/30] -- Thread 2264 PreRenderComplete&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:14pt;FONT-FAMILY:'Courier New';"&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:14pt;FONT-FAMILY:'Courier New';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Ecco in gioco un altro thread (notare che i numeri, anche se casualmente, sono gli stessi proprio perchè i thread vengono recuperati dal thread pool) per eseguire la seconda richiesta asincrona e il conseguente risultato.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Sembra tutto perfetto: siamo risciti a parallelizzare le richieste abbassando il tempo totale di risposta....ma &lt;B&gt;le insidie sono ben nascoste dietro questo esempio&lt;/B&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;In questo esempio, infatti, stiamo provando la pagina con un solo browser e analizzando i migliorati tempi di risposta...ma cosa succede se effettuiamo più richieste in contemporanea ?&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Due dati per capire il problema con un carico di 20 client:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;La pagina con la chiamata a un web service che in sincrono impiegava 16,3 secondi passa con una chiamata asincrona a 21.6 secondi !!! e il processore passa dal 24% di carico al 29%; ottimo lavoro &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Wingdings;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:Arial;mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;&lt;SPAN style="mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;J&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt; abbiamo peggiorato e parecchio i tempi di risposta e nel contempo caricato di più la macchina.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Purtroppo questo esempio viene citato da molti come la soluzione al problema di parallelizzare le richieste "Se una pagina chiama un web service occorre farlo in asincrono in modo da sfruttare i tempi morti": questo è quello che viene sbandierato da tanti. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Abbiamo invece dimostrato che questa soluzione peggiora i tempi di esecuzione totali della applicazione ! Il problema di fondo è che la chiamata a BeginMetodo impegna un altro thread del thread pool senza liberare il thread corrente, quindi a fronte di una richiesta per la pagina che effettua una chiamata al web service avremo due thread del thread pool impegnati e nella richiesta per la pagina che effettua due chiamate 3 thread del thread pool impegnati per tutta la durata della richiesta: questo il motivo per cui i tempi di esecuzione totali con richieste concorrenti va peggiorare le performance invece di migliorarle; pensate a 6 richieste concorrenti che fanno lavorare (6*3) 18 thread…esaurendo quasi i 20 thread a disposizione.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;La soluzione la vedremo nel &lt;FONT color=#006ff7&gt;prossimo articolo&lt;/FONT&gt; (più avanti nel testo) e consta nel rendere asincrona anche l'esecuzione della pagina da parte del motore di ASP.NET. Questa soluzione si può ottenere anche in ASP.NET 1.x implementando l'interfaccia IHttpAsyncHandler, ma perdendo molti degli automatismi di ASP.NET nell'uso dei controlli e nella gestione dello stato. In ASP.NET 2.0 ci hanno facilitato la vita tramite un attributo della pagina che consente in automatico di generare dietro le quinte l'implementazione di IHttpAsyncHandler.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Nel prossimo articolo vedremo le tecniche all'opera sia per ASP.NET 1.x che per ASP.NET 2.0 analizzando anche i metodi più automatizzati come AddOnPreRenderCompleteAysnc e Page Task.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Vi ricordo che all'indirizzo http://thinkmobile.it:9000/async ho pubblicato tutte le demo (anche quelle del prossimo articolo) così potete provare da remoto le varie demo senza riscrivere il codice: il menù di sinistra vi porta ai vari esempi analizzati. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Vi chiedo un favore: visto che il sito thinkmobile.it è una comunità per tutti gli sviluppatori mobile (fra cui gli sviluppatori web mobile in ASP.NET 1.x e 2.0) vi pregherei di non effettuare stress test direttamente sull'indirizzo pubblico ma semplicemente visualizzare live gli esempi e copiare il codice per effettuare stress test privati sui vostri server.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Nel &lt;A class="" href="http://blogs.devleap.com/rob/pages/asp-net-2-0-async-techniques-parte-1.aspx" target=_blank&gt;&lt;FONT color=#006ff7&gt;precedente articolo&lt;/FONT&gt;&lt;/A&gt; abbiamo introdotto le problematiche di programmazione asincrona (e di conseguenza multithread) in ASP.NET, ripercorrendo passo per passo, con esempi semplici, i motivi per cui, effettuare chiamate asincrone, di per sè, peggiora le performance globali della nostra applicazione. Riporto il punto finale dell’articolo per proseguire con l’analisi della soluzione al problema. Ci siamo lasciati con una pagina sincrona (il default) che chiama due web service con il pattern asincrono Begin/EndMetodo. Questi erano i dati di performance con un carico di soli 20 client.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;La pagina con la chiamata ad un web service che in sincrono impiegava 16,3 secondi passa con una chiamata asincrona a 21.6 secondi !!! e il processore passa dal 24% di carico al 29%; ottimo lavoro &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Wingdings;mso-ascii-font-family:Arial;mso-hansi-font-family:Arial;mso-bidi-font-family:Arial;mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;&lt;SPAN style="mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;J&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt; abbiamo peggiorato e parecchio i tempi di risposta e nel contempo caricato di più la macchina.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Purtroppo questo esempio viene citato da molti come la soluzione al problema di parallelizzare le richieste "Se una pagina chiama un web service deve farlo in asincrono in modo da sfruttare i tempi morti": questo è quello che viene sbandierato da tanti. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Abbiamo invece dimostrato che questa soluzione peggiora i tempi di esecuzione totali della applicazione ! Il problema di fondo è che la chiamata a BeginMetodo impegna un altro thread del thread pool senza liberare il thread corrente, quindi, a fronte di una richiesta per la pagina che effettua una chiamata al web service, avremo 2 thread del thread pool impegnati e nella richiesta per la pagina che effettua due chiamate 3 thread del thread pool impegnati per tutta la durata della richiesta: questo è il motivo per cui i tempi di esecuzione totali con richieste concorrenti peggiorano le performance invece di migliorarle; pensate a 6 richieste concorrenti che fanno lavorare (6*3) 18 thread…esaurendo quasi i 20 thread a disposizione.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;La soluzione al problema consiste nel rendere asincrona anche l'esecuzione della pagina da parte del motore di ASP.NET. Questa soluzione si può ottenere anche in ASP.NET 1.x implementando l'interfaccia IHttpAsyncHandler, ma perdendo molti degli automatismi di ASP.NET nell'uso dei controlli e nella gestione dello stato. In ASP.NET 2.0 ci hanno facilitato la vita tramite un attributo della pagina che consente in automatico di generare dietro le quinte l'implementazione di IHttpAsyncHandler.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Vi ricordo che all'indirizzo http://thinkmobile.it:9000/async ho pubblicato tutte le demo (anche quelle del precedente articolo) così potete provare da remoto le varie demo senza riscrivere il codice: il menù di sinistra vi porta ai vari esempi analizzati. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Partiamo da ASP.NET 1.x. Per rendere asincrona l’esecuzione di una pagina occorre implementare IAsyncHttpHandler. &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';mso-ansi-language:EN-US;"&gt;Ecco il codice:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';mso-ansi-language:EN-US;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';mso-ansi-language:EN-GB;"&gt;---- 05AsyncHandler.ashx ---&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-highlight:yellow;mso-no-proof:yes;"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;@&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:maroon;"&gt;WebHandler&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Language&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="C#"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Class&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="SyncHandler10"&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-highlight:yellow;mso-no-proof:yes;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;using&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt; System;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;using&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt; System.Threading;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;using&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt; System.Web;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;public&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:blue;"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR:teal;"&gt;SyncHandler10&lt;/SPAN&gt; : &lt;SPAN style="COLOR:teal;"&gt;IHttpAsyncHandler&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;{&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;SalesmanManagerWS.&lt;SPAN style="COLOR:teal;"&gt;SalesmanManagerWS&lt;/SPAN&gt; ws;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:teal;"&gt;HttpContext&lt;/SPAN&gt; ctx;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:teal;"&gt;IAsyncResult&lt;/SPAN&gt; &lt;SPAN style="COLOR:teal;"&gt;IHttpAsyncHandler&lt;/SPAN&gt;.BeginProcessRequest(&lt;SPAN style="COLOR:teal;"&gt;HttpContext&lt;/SPAN&gt; context, &lt;SPAN style="COLOR:teal;"&gt;AsyncCallback&lt;/SPAN&gt; cb, &lt;SPAN style="COLOR:blue;"&gt;object&lt;/SPAN&gt; state) &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ctx = context;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ws = &lt;SPAN style="COLOR:blue;"&gt;new&lt;/SPAN&gt; SalesmanManagerWS.&lt;SPAN style="COLOR:teal;"&gt;SalesmanManagerWS&lt;/SPAN&gt;();&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ctx.Response.Output.Write(&lt;SPAN style="COLOR:maroon;"&gt;"&amp;lt;p&amp;gt;Thread "&lt;/SPAN&gt; + &lt;SPAN style="COLOR:teal;"&gt;AppDomain&lt;/SPAN&gt;.GetCurrentThreadId());&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;return&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; ws.BeginSalvaAgente(&lt;SPAN style="COLOR:maroon;"&gt;"robertob"&lt;/SPAN&gt;, &lt;SPAN style="COLOR:maroon;"&gt;"Roberto Brunetti"&lt;/SPAN&gt;, cb, ws);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;void&lt;/SPAN&gt; &lt;SPAN style="COLOR:teal;"&gt;IHttpAsyncHandler&lt;/SPAN&gt;.EndProcessRequest(&lt;SPAN style="COLOR:teal;"&gt;IAsyncResult&lt;/SPAN&gt; asyncResult) &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ctx.Response.Output.Write(&lt;SPAN style="COLOR:maroon;"&gt;"&amp;lt;p&amp;gt;Thread "&lt;/SPAN&gt; + &lt;SPAN style="COLOR:teal;"&gt;AppDomain&lt;/SPAN&gt;.GetCurrentThreadId());&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ctx.Response.Output.Write(((SalesmanManagerWS.&lt;SPAN style="COLOR:teal;"&gt;SalesmanManagerWS&lt;/SPAN&gt;)asyncResult.AsyncState).EndSalvaAgente(asyncResult).ToString());&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;void&lt;/SPAN&gt; &lt;SPAN style="COLOR:teal;"&gt;IHttpHandler&lt;/SPAN&gt;.ProcessRequest(&lt;SPAN style="COLOR:teal;"&gt;HttpContext&lt;/SPAN&gt; context) {&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR:teal;"&gt;InvalidOperationException&lt;/SPAN&gt;();&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;bool&lt;/SPAN&gt; &lt;SPAN style="COLOR:teal;"&gt;IHttpHandler&lt;/SPAN&gt;.IsReusable {&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;get&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; { &lt;SPAN style="COLOR:blue;"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;false&lt;/SPAN&gt;; }&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;}&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Questa pagina, in realtà questo codice, sfrutta l’estensione .ashx che ci evita, in questo semplice esempio, di dover creare un Http Handler esterno e registrarlo nel web.config (tecnica consigliata nella maggior parte dei casi in produzione).&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Come si nota dall’esempio, la nostra classe, implementa IHttpAsyncHandler e consente, tramite i due metodi BeginProcessRequest e EndProcessRequest di effettuare chiamate asincrone ai web service. In pratica, il motore di ASP.NET rende asincrona l’esecuzione dell’handler, liberando il thread corrente (rimettendolo nel Thread Pool) dopo la chiamata a BeginProcessRequest. Questo significa, appunto, non occupare un thread del thread pool durante la richiesta asincrona al nostro, ormai famoso, web service.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Anche se i tempi di esecuzione sotto stress migliorano notevolmente rispetto a quanto abbiamo visto nell’ultima parte dell’articolo precedente, ci perdiamo il bello di ASP.NET, cioè la possibilità di lavorare con i controlli e gli eventi a livello di pagina: occorre fare tutto da codice.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Un workaround che uso spesso è quello di cercare di mantenere asincrona l’esecuzione dell’handler cercando di evitare la codifica della risposta a manina.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Una prima soluzione è quella di implementare la chiamata asincrona dentro il Global.asax, inserire il risultato in una variabile del contesto http (HttpContext.Items[“Risultato”] ad esempio) per poi recuperare questo elemento da una normale pagina sincrona. Il problema di questo approccio è dover riempire il Global.asax di If e Switch per invocare i web service corretti solo per le richieste a pagine che utilizzano web service.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Un secondo approccio più elegante, di cui vediamo il codice, è invece creare un handler .ashx per ogni pagina che necessita di effettuare chiamate asincrone.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Ad esempio, la pagina 06AsyncContext.aspx avrà un corrispondente 06AsyncHanderContext.ashx. Nell’handler asincrono chiameremo (sempre in asincrono, ovviamente) il web service. Alla ricezione della risposta (EndMethod) mettiamo il risultato in una variabile del contesto http e eseguiamo una Redirect verso la pagina reale, che, a questo punto, può usare Web Control e eventi nel modo tradizionale e recuperare il risultato dalla variabile del contesto. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';mso-ansi-language:EN-GB;"&gt;Ecco l’esempio:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-highlight:yellow;mso-no-proof:yes;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-highlight:yellow;mso-no-proof:yes;"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;@&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:maroon;"&gt;WebHandler&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Language&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="C#"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Class&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="SyncHandler10"&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-highlight:yellow;mso-no-proof:yes;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;using System;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;using System.Threading;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;using System.Web;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;public class SyncHandler10 : IHttpAsyncHandler &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;{&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;SalesmanManagerWS.SalesmanManagerWS ws;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;HttpContext ctx;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, object state) &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ctx = context;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ws = new SalesmanManagerWS.SalesmanManagerWS();&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;return ws.BeginSalvaAgente("robertob", "Roberto Brunetti", cb, ws);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;void IHttpAsyncHandler.EndProcessRequest(IAsyncResult asyncResult) &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ctx.Items["RisultatoWS"] = ((SalesmanManagerWS.SalesmanManagerWS)asyncResult.AsyncState).EndSalvaAgente(asyncResult).ToString();&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ctx.Server.Execute("~/06AsyncContext10.aspx");&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;void IHttpHandler.ProcessRequest(HttpContext context) {&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;throw new InvalidOperationException();&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;bool IHttpHandler.IsReusable {&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;get { return true; }&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;}&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;L’handler esegue la chiamata a BeginSalvaAgente e dopo aver ricevuto il risultato in EndProcessRequest, lo inserisce in HttpContext con il nome di RisultatoWS. L’esecuzione viene poi rediretta sulla pagina con una Server.Execute. La pagina, a questo punto, può utilizzare Web Control e eventi e recuperare il risultato dal Context. Ecco il codice della pagina:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-highlight:yellow;mso-no-proof:yes;"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;@&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:maroon;"&gt;Page&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Language&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="C#"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;AutoEventWireup&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="true"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;MasterPageFile&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="~/MasterPage.master"&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-highlight:yellow;mso-no-proof:yes;"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;@&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:maroon;"&gt;MasterType&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;VirtualPath&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="~/MasterPage.master"&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-highlight:yellow;mso-no-proof:yes;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:maroon;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;script&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:red;"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="server"&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;void&lt;/SPAN&gt; Page_Load() {&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Master.AddTraceMessage(&lt;SPAN style="COLOR:maroon;"&gt;"Salva Agente Async da Global.asax"&lt;/SPAN&gt;);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Master.AddTraceMessage(&lt;SPAN style="COLOR:maroon;"&gt;"Risultato "&lt;/SPAN&gt; + Context.Items[&lt;SPAN style="COLOR:maroon;"&gt;"RisultatoWS"&lt;/SPAN&gt;].ToString());&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:maroon;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;script&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Ottimo ! Abbiamo reso asincrona l’esecuzione della pagina senza incasinarci più di tanto. Ricordatevi che i link dalle altre pagine non devono puntare a pagina.aspx ma verso pagina.ashx.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;In ASP.NET 2.0 ci hanno facilitato notevolmente il compito rendendo trasparente l’implementazione di IHttpAsyncHandler. È sufficiente decorare una pagina con l’attributo Async=”true” per avviare questo processo. Un ulteriore “miglioramento” della versione 2.0 di .NET è un nuovo pattern per le chiamate asincrone. Vediamo entrambi questi aspetti nel codice seguente.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-highlight:yellow;mso-no-proof:yes;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;--- 09ChiamaUnWebService.aspx ---&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-highlight:yellow;mso-no-proof:yes;"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;@&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:maroon;"&gt;Page&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Language&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="C#"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Async&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;="true"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;MasterPageFile&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="~/MasterPage.master"&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-highlight:yellow;mso-no-proof:yes;"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;@&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:maroon;"&gt;MasterType&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;VirtualPath&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="~/MasterPage.master"&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-highlight:yellow;mso-no-proof:yes;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:maroon;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;script&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:red;"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="server"&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;void&lt;/SPAN&gt; Page_Load() {&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Master.AddTraceMessage(&lt;SPAN style="COLOR:maroon;"&gt;"SalvaAgente 2.0 Async"&lt;/SPAN&gt;);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;SalesmanManagerWS.&lt;SPAN style="COLOR:teal;"&gt;SalesmanManagerWS&lt;/SPAN&gt; ws = &lt;SPAN style="COLOR:blue;"&gt;new&lt;/SPAN&gt; SalesmanManagerWS.&lt;SPAN style="COLOR:teal;"&gt;SalesmanManagerWS&lt;/SPAN&gt;();&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;// Nuova riga&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ws.SalvaAgenteCompleted += &lt;SPAN style="COLOR:blue;"&gt;this&lt;/SPAN&gt;OnSalvaAgenteCompleted; &lt;SPAN style="COLOR:green;"&gt;// Non occre definire il delegate (fa lui)&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;// Non servono più&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;//IAsyncResult ar = ws.BeginSalvaAgente("robertob", "RobertoBrunetti", AgenteSalvato, ws);&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;//ar.AsyncWaitHandle.WaitOne();&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ws.SalvaAgenteAsync(&lt;SPAN style="COLOR:maroon;"&gt;"Robertob"&lt;/SPAN&gt;, &lt;SPAN style="COLOR:maroon;"&gt;"RobertoBrunetti"&lt;/SPAN&gt;);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Master.AddTraceMessage(&lt;SPAN style="COLOR:maroon;"&gt;"SalvaAgente 2.0 Fine Chiamata"&lt;/SPAN&gt;);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;//Definizione più conforme alla normale gestione eventi&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;// private void AgenteSalvato(IAsyncResult ar)&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;void&lt;/SPAN&gt; OnSalvaAgenteCompleted(&lt;SPAN style="COLOR:blue;"&gt;object&lt;/SPAN&gt; sender, SalesmanManagerWS.&lt;SPAN style="COLOR:teal;"&gt;SalvaAgenteCompletedEventArgs&lt;/SPAN&gt; e)&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;// N.B. Typed Result (SalvaAgenteCompletedEventArgs)&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;// N.B. Il thread che esegue questo codice non è detto che sia lo stesso del Page_Load&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Master.AddTraceMessage(&lt;SPAN style="COLOR:maroon;"&gt;"SalvaAgente 2.0 Completed"&lt;/SPAN&gt;);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:green;"&gt;// Via sto casino&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;// SalesmanManagerWS.SalesmanManagerWS ws = (SalesmanManagerWS.SalesmanManagerWS)ar.AsyncState;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;// bool ris = ws.EndSalvaAgente(ar);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;bool&lt;/SPAN&gt; ris = e.Result;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-GB;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;Master.AddTraceMessage(&lt;SPAN style="COLOR:maroon;"&gt;"Risultato "&lt;/SPAN&gt; + ris.ToString());&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:maroon;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;script&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Nell’esempio è stato usato il nuovo attributo Async=”true”. Nel codice trovate commentate le righe utilizzate in precedenza con il pattern Begin/End Metodo. Come si può notare il codice si è semplificato notevolmente. La chiamata al Web Service si effettua tramite il MetodoAsync (nel nostro caso SalvaAgenteAsync; esiste un EventHandler OnSalvaAgenteCompleted che semplifica il recupero dei risultati. In questo nuovo pattern, infatti, il risultato è tipizzato (SalvaAgenteCompletedEventArgs viene definito in automatico alla creazione del proxy) e sicuramente il codice è più semplice da leggere rispetto all’utilizzo di IAsyncResult e AsyncState.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Sul sito trovate anche un esempio di chiamata a due web service, sia in parallelo che in sequenza (nel caso in cui la chiamata al secondo abbia bisogno di un parametro che deriva dall’esecuzione del primo) che ometto per brevità.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Tutte le chiamate asincrone devono essere effettuate prima dell’Async Point: questo nuovo termine indica il punto in cui il motore di ASP.NET sospende l’esecuzione del thread corrente e reinserisce il thread nel thread pool. Quando terminano le operazioni asincrone viene recuperato un thread del thread pool per inviare la risposta al client. In pratica l’esecuzione della pagina viene sospesa sull’async point se ci sono richieste asincrone in corso e ripresa al termine della loro esecuzione. Se sull’async point le operazioni asincrone sono già terminate (nel nostro caso il web service ha già restituito una risposta) il thread non viene sospeso ma prosegue la sua esecuzione. Questa è una tecnica veramente molto efficiente.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Dov’è l’Async Point ? Questo “punto” di esecuzione della pipeline di una pagina si trova in corrispondenza dell’evento PreRenderComplete: questo significa che le chiamate asincrone possono essere effettuate in tutti gli eventi della pagina che vengono scatenati prima di PreRenderComplete. In pratica è consentito effettuare una chiamata asincrona negli eventi Page_PreInit, Page_Init, Page_InitComplete, Page_PreLoad, Page_LoadComplete, Page_PreRender. Non è possibile effettuare chiamate asincrone (o meglio è possibile ma non possono beneficiare di una reale chiamata asincrona) dagli eventi Page_PreRenderComplete, Page_SaveState, Page_SaveStateComplete, Page_Render, Page_Unload.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Nell’esempio precedente abbiamo usato il nuovo pattern MetodoAsync al posto del Begin/EndMetodo. Ci sono però alcune limitazioni nel nuovo pattern: non tutti i componenti .NET implementano questo pattern: ad esempio non è possibile utilizzarlo con chiamate asincrone verso i componenti di ADO.NET 2.0 in quanto non implementano questo pattern. Di conseguenza, conviene prendere la mano con il pattern Begin/EndMetodo, anche se più complicato da leggere/scrivere in quanto disponibile per tutti i componenti .NET che consentono chiamate asincrone. Il metodo Begin/End, però ha una limitazione (anche nella versione 1.x), cioè non fa confluire nella parte End della chiamata (la callback) Impersonation, Culture e HttpContext.Current che vanno reimpostati. Il nuovo pattern MetodoAysnc, al contrario, passa Impersonation, Culture e HttpContext al metodo di callback.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Riassumendo MetodoAysnc è più semplice da usare, ha il risultato tipizzato e lavora sul metodo di callback con lo stesso criterio di Impersonation, Culture e sullo stesso HttpContext (HttpContext.Current), ma non è implementato in molti componenti del .NET Framework. Il metodo Begin/End, anche se è utilizzabile con tutti i componenti asincroni, complica un po’ il codice e non esegue il metodo di callback con gli stessi criteri di Impersonation e Culture e nello stesso contesto http. A voi la scelta.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Sul sito trovate le demo 09, 10, 11 e 12 sul pattern MetodoAsync/Completed e le demo 13 e 14 con il pattern Begin/End.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;Riporto per completezza gli esempi in sequenza:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-pagination:none;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Arial','sans-serif';"&gt;--- 10 Chiamata a due Web Service in sequenza ---&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-highlight:yellow;mso-no-proof:yes;"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;@&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:maroon;"&gt;Page&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Language&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="C#"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;Async&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;="true"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;MasterPageFile&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="~/MasterPage.master"&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-highlight:yellow;mso-no-proof:yes;"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;@&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:maroon;"&gt;MasterType&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;VirtualPath&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="~/MasterPage.master"&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;BACKGROUND:yellow;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-highlight:yellow;mso-no-proof:yes;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:maroon;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;script&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:red;"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="server"&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;O:P&gt;&amp;nbsp;&lt;/O:P&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;void&lt;/SPAN&gt; Page_Load() {&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Master.AddTraceMessage(&lt;SPAN style="COLOR:maroon;"&gt;"SalvaAgente 2.0 Async"&lt;/SPAN&gt;);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;SalesmanManagerWS.&lt;SPAN style="COLOR:teal;"&gt;SalesmanManagerWS&lt;/SPAN&gt; ws = &lt;SPAN style="COLOR:blue;"&gt;new&lt;/SPAN&gt; SalesmanManagerWS.&lt;SPAN style="COLOR:teal;"&gt;SalesmanManagerWS&lt;/SPAN&gt;();&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;ws.SalvaAgenteCompleted += &lt;SPAN style="COLOR:blue;"&gt;this&lt;/SPAN&gt;OnSalvaAgenteCompleted;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ws.SalvaAgenteAsync(&lt;SPAN style="COLOR:maroon;"&gt;"Robertob"&lt;/SPAN&gt;, &lt;SPAN style="COLOR:maroon;"&gt;"RobertoBrunetti"&lt;/SPAN&gt;);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Master.AddTraceMessage(&lt;SPAN style="COLOR:maroon;"&gt;"SalvaAgente 2.0 Fine Chiamata"&lt;/SPAN&gt;);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0cm 0cm 0pt;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;}&l