<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>AntonioGanci</title>
        <link>http://blogs.ugidotnet.org/AntonioGanci/Default.aspx</link>
        <description>Il blog di Antonio Ganci</description>
        <language>it-IT</language>
        <copyright>Antonio Ganci</copyright>
        <managingEditor>ugog91@yahoo.it</managingEditor>
        <generator>Subtext Version 1.9.5.176</generator>
        <image>
            <title>AntonioGanci</title>
            <url>http://blogs.ugidotnet.org/images/RSS2Image.gif</url>
            <link>http://blogs.ugidotnet.org/AntonioGanci/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <item>
            <title>Scrivere uno unit test per l'accesso esclusivo ad una risorsa condivisa da diversi thread - Alcune considerazioni</title>
            <link>http://blogs.ugidotnet.org/AntonioGanci/archive/2008/08/23/93789.aspx</link>
            <description>&lt;p&gt;   Vorrei rispondere ad alcuni commenti del mio precedente &lt;a href="http://blogs.ugidotnet.org/AntonioGanci/archive/2008/08/17/93727.aspx"&gt;post&lt;/a&gt;.   Il primo di &lt;a href="http://blogs.ugidotnet.org/makka/Default.aspx"&gt;Claudio Maccari&lt;/a&gt;  &lt;/p&gt;
&lt;p&gt;&lt;cite&gt;  Nel tuo esempio crei un thread per ogni OrderThread e non credo sia la cosa più efficente da fare. meglio usare ThreadPool.QueueUserWorkItem Io scriverei così all'interno di OrderThread&lt;br /&gt;
&lt;br /&gt;
public void Start()&lt;br /&gt;
{&lt;br /&gt;
ThreadPool.QueueUserWorkItem(delegate { _broker.PlaceOrder(_order); });&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ma in questo caso non saprei come scrivere uno unit-test adeguato. tu come faresti ? &lt;/cite&gt; &lt;/p&gt;
&lt;p&gt;  Per prima cosa cambiamo l'implementazione della classe OrderThread in modo che utilizzi un ThreadPool: &lt;/p&gt;
&lt;div style="background: rgb(24, 24, 24) none repeat scroll 0% 0%; font-family: Consolas; font-size: 12pt; color: rgb(224, 224, 224); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;pre style="margin: 0px;"&gt;    &lt;span style="color: rgb(128, 128, 192);"&gt;class&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;OrderThread&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;    {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;IBroker&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;_broker&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;Order&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;_order&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;Thread&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;_thread&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;OrderThread&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;IBroker&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;broker&lt;/span&gt;, &lt;span style="color: rgb(199, 199, 241);"&gt;Order&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;order&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;_broker&lt;/span&gt; = &lt;span style="color: rgb(254, 241, 169);"&gt;broker&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;_order&lt;/span&gt; = &lt;span style="color: rgb(254, 241, 169);"&gt;order&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;bool&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;IsWaiting&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(128, 128, 192);"&gt;get&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;                &lt;span style="color: rgb(128, 128, 192);"&gt;if&lt;/span&gt; (&lt;span style="color: rgb(254, 241, 169);"&gt;_thread&lt;/span&gt; == &lt;span style="color: rgb(128, 128, 192);"&gt;null&lt;/span&gt;) &lt;span style="color: rgb(128, 128, 192);"&gt;return&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;false&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;                &lt;span style="color: rgb(128, 128, 192);"&gt;return&lt;/span&gt; (&lt;span style="color: rgb(254, 241, 169);"&gt;_thread&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;ThreadState&lt;/span&gt; &amp;amp; &lt;span style="color: rgb(199, 199, 241);"&gt;ThreadState&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;WaitSleepJoin&lt;/span&gt;) &amp;gt; 0;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;Start&lt;/span&gt;()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(199, 199, 241);"&gt;ThreadPool&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;QueueUserWorkItem&lt;/span&gt;(&lt;span style="color: rgb(128, 128, 192);"&gt;delegate&lt;/span&gt; { &lt;span style="color: rgb(254, 241, 169);"&gt;PlaceOrder&lt;/span&gt;(); });&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;PlaceOrder&lt;/span&gt;()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;_thread&lt;/span&gt; = &lt;span style="color: rgb(199, 199, 241);"&gt;Thread&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;CurrentThread&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;_broker&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;PlaceOrder&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;_order&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;    }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;  Ho dovuto modificare l'implementazione della property IsWaiting perchè i thread creati dal ThreadPool sono Background thread.  &lt;/p&gt;
&lt;p&gt;  Ora lanciamo il test che è rimasto uguale rispetto al precedente   &lt;a href="http://blogs.ugidotnet.org/AntonioGanci/archive/2008/08/17/93727.aspx"&gt;post&lt;/a&gt;. L'output generato è il seguente: &lt;/p&gt;
&lt;p class="style1" style="font-family: Courier New;"&gt; TestCase 'OrderThreadTests.Access_To_The_Broker_Should_Be_Synchronized' failed:  Equal assertion failed: [[1]]!=[[2]] &lt;/p&gt;
&lt;p&gt;  In pratica entrambi i thread sono all'interno del metodo PlaceOrder del Broker! Abbiamo una race condition.   Questo è normale perchè non abbiamo sincronizzato l'accesso al Broker. &lt;/p&gt;
&lt;p&gt;  Modifichiamo quindi il metodo privato PlaceOrder aggiungendo una lock: &lt;/p&gt;
&lt;div style="background: rgb(24, 24, 24) none repeat scroll 0% 0%; font-family: Consolas; font-size: 12pt; color: rgb(224, 224, 224); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;PlaceOrder&lt;/span&gt;()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;_thread&lt;/span&gt; = &lt;span style="color: rgb(199, 199, 241);"&gt;Thread&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;CurrentThread&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(128, 128, 192);"&gt;lock&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;_broker&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;                &lt;span style="color: rgb(254, 241, 169);"&gt;_broker&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;PlaceOrder&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;_order&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;  Ora rilanciamo il test: &lt;/p&gt;
&lt;p style="font-family: Courier New;"&gt;     &lt;span class="style1"&gt;[success] OrderThreadTests.Access_To_The_Broker_Should_Be_Synchronized&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;  Ed ecco che abbiamo cambiato l'implentazione della classe OrderTest senza modificare il test.   Ci si potrebbe chiedere perchè non ho utilizzato subito un ThreadPool, il motivo è che nell'applicazione questi thread  seguono anche lo stato dell'ordine ed hanno quindi una vita molto lunga (un ordine può essere eseguito dopo qualche  ora che è stato immesso) e mi serviva avere un riferimento al thread per sincronizzarli tra di loro.&lt;/p&gt;
&lt;p&gt;  Alcune considerazioni sullo unit testing per il multithreading: &lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Lo unit test &lt;strong&gt;NON&lt;/strong&gt; garantisce l'assenza di problemi di sincronizzazione              come in generale non garantisce l'assenza di bug. In questo caso però              modificando l'implementazione con quella proposta di Claudio ha fatto subito              emergere il problema di essersi dimenticato il lock&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
    &lt;li&gt;Il TDD in questi casi serve soprattutto a far emergere un'architettura              facilmente testabile&lt;/li&gt;
    &lt;li&gt;Il Multithreading aggiunge molta complessità al codice questo rende difficile              anche la scrittura dei test i quali potrebbero dipendere dal pc su cui girano              perchè a chi li ha scritti è sfuggita qualche condizione di concorrenza.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;         Vorrei infine segnalare il post &lt;a href="http://googletesting.blogspot.com/2008/08/tott-sleeping-synchronization.html"&gt;TotT: Sleeping != Synchronization&lt;/a&gt;         del &lt;a href="http://googletesting.blogspot.com/2008/08/tott-sleeping-synchronization.html"&gt;Google Testing Blog&lt;/a&gt; che tratta lo stesso argomento, il codice         è scritto in ruby ma non dovrebbero esserci molte difficoltà a comprenderlo.     &lt;/p&gt;&lt;img src="http://blogs.ugidotnet.org/AntonioGanci/aggbug/93789.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Antonio Ganci</dc:creator>
            <guid>http://blogs.ugidotnet.org/AntonioGanci/archive/2008/08/23/93789.aspx</guid>
            <pubDate>Sat, 23 Aug 2008 09:40:30 GMT</pubDate>
            <wfw:comment>http://blogs.ugidotnet.org/AntonioGanci/comments/93789.aspx</wfw:comment>
            <comments>http://blogs.ugidotnet.org/AntonioGanci/archive/2008/08/23/93789.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/AntonioGanci/comments/commentRss/93789.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/AntonioGanci/services/trackbacks/93789.aspx</trackback:ping>
        </item>
        <item>
            <title>Google Testing Blog</title>
            <link>http://blogs.ugidotnet.org/AntonioGanci/archive/2008/08/18/93733.aspx</link>
            <description>Vorrei segnalare il blog &lt;a href="http://googletesting.blogspot.com/"&gt;Google Testing Blog&lt;/a&gt; in particolare dall'ultimo &lt;a href="http://googletesting.blogspot.com/2008/08/by-miko-hevery-so-you-join-new-project.html"&gt;post&lt;/a&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;Singletons are nothing more than global state. Global state makes it so your objects can secretly get hold of things which are not declared in their APIs, and, as a result, Singletons make your APIs into pathological liars.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Questo l'ho anche visto quando si abusa dei framework di IoC risalire alle dipendenze di un oggetto diventa un'ardua impresa.&lt;img src="http://blogs.ugidotnet.org/AntonioGanci/aggbug/93733.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Antonio Ganci</dc:creator>
            <guid>http://blogs.ugidotnet.org/AntonioGanci/archive/2008/08/18/93733.aspx</guid>
            <pubDate>Mon, 18 Aug 2008 06:54:46 GMT</pubDate>
            <wfw:comment>http://blogs.ugidotnet.org/AntonioGanci/comments/93733.aspx</wfw:comment>
            <comments>http://blogs.ugidotnet.org/AntonioGanci/archive/2008/08/18/93733.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/AntonioGanci/comments/commentRss/93733.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/AntonioGanci/services/trackbacks/93733.aspx</trackback:ping>
        </item>
        <item>
            <title>Come scrivere uno unit test per controllare l'accesso esclusivo ad una risorsa condivisa da diversi thread</title>
            <category>Extreme Programming</category>
            <link>http://blogs.ugidotnet.org/AntonioGanci/archive/2008/08/17/93727.aspx</link>
            <description>&lt;p&gt;Nel mio precedente &lt;a href="http://blogs.ugidotnet.org/AntonioGanci/archive/2008/06/06/92951.aspx"&gt;post&lt;/a&gt;   ho affrontato il problema di come sviluppare usando il TDD un'applicazione multithreading.  &lt;/p&gt;
&lt;p&gt;   In questo post, cercherò di approfondire su come testare la sincronizzazione per l'accesso ad una risorsa condivisa.  &lt;/p&gt;
&lt;p&gt;   L'obiettivo che voglio raggiungere è scrivere un test che fallisca se non applico un meccanismo di sincronizzazione    (in questo caso la lock) per l'accesso alla risorsa e abbia successo quando viene introdotta       la sincronizzazione.   Il fatto che il test abbia successo deve essere sistematico e non deve esserci nessun elemento di casualità       come l'ordine di schedulazione la velocità del processore.  &lt;/p&gt;
&lt;p&gt;   Vediamo di descrivere lo scenario. La risorsa condivisa è il Broker la cui responsabilità è quella di immettere sul   mercato azionario un ordine di acquisto o vendita di azioni. La classe Broker implementa la seguente interfaccia:  &lt;/p&gt;
&lt;div style="background: rgb(24, 24, 24) none repeat scroll 0% 0%; font-family: Consolas; font-size: 12pt; color: rgb(224, 224, 224); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;pre style="margin: 0px;"&gt;    &lt;span style="color: rgb(128, 128, 192);"&gt;interface&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;IBroker&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;    {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;PlaceOrder&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;Order&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;order&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;    }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;  La classe Order che non riporterò contiene i dati necessari per immettere l'ordine come il prezzo, la quantità di azioni, ecc. &lt;/p&gt;
&lt;p&gt;  L'ultimo elemento di questo scenario è la classe OrderThread, la sua responsabilità è quella di eseguire il metodo PlaceOrder  in un thread creato da lei. &lt;/p&gt;
&lt;div style="background: rgb(24, 24, 24) none repeat scroll 0% 0%; font-family: Consolas; font-size: 12pt; color: rgb(224, 224, 224); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;pre style="margin: 0px;"&gt;    &lt;span style="color: rgb(128, 128, 192);"&gt;class&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;OrderThread&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;    {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;IBroker&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;_broker&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;Order&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;_order&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;OrderThread&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;IBroker&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;broker&lt;/span&gt;, &lt;span style="color: rgb(199, 199, 241);"&gt;Order&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;order&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;_broker&lt;/span&gt; = &lt;span style="color: rgb(254, 241, 169);"&gt;broker&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;_order&lt;/span&gt; = &lt;span style="color: rgb(254, 241, 169);"&gt;order&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;Start&lt;/span&gt;()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(199, 199, 241);"&gt;Thread&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;thread&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;Thread&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;PlaceOrder&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;thread&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Start&lt;/span&gt;();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;PlaceOrder&lt;/span&gt;()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;_broker&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;PlaceOrder&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;_order&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;    }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;  Come si può notare alla chiamata PlaceOrder non viene usato nessun meccanismo di sincronizzazione. Quindi due istanze  di OrderThread che utilizzino lo stesso broker potrebbero chiamare contemporaneamente il metodo PlaceOrder dando  luogo ad una &lt;a href="http://it.wikipedia.org/wiki/Race_condition"&gt;race condition&lt;/a&gt;.  Vogliamo scrivere un test che abbia successo se la race condition non possa      verificarsi e fallisca altrimenti. &lt;/p&gt;
&lt;p&gt;  Per ottenere il risultato scriviamo un'implementazione dell'interfaccia IBroker pilotabile dal nostro test che ci  permetta di simulare lo scenario in cui due OrderThread cerchino di chiamare contemporaneamente il metodo PlaceOrder. &lt;/p&gt;
&lt;div style="background: rgb(24, 24, 24) none repeat scroll 0% 0%; font-family: Consolas; font-size: 12pt; color: rgb(224, 224, 224); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;pre style="margin: 0px;"&gt;    &lt;span style="color: rgb(128, 128, 192);"&gt;class&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;SleepingBroker&lt;/span&gt; : &lt;span style="color: rgb(199, 199, 241);"&gt;IBroker&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;    {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;ManualResetEvent&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;_resetEvent&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;ManualResetEvent&lt;/span&gt;(&lt;span style="color: rgb(128, 128, 192);"&gt;false&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;int&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;CallingPlaceOrderCount&lt;/span&gt; { &lt;span style="color: rgb(128, 128, 192);"&gt;get&lt;/span&gt;; &lt;span style="color: rgb(128, 128, 192);"&gt;set&lt;/span&gt;;}&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;PlaceOrder&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;Order&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;order&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;CallingPlaceOrderCount&lt;/span&gt;++;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;_resetEvent&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;WaitOne&lt;/span&gt;();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;CallingPlaceOrderCount&lt;/span&gt;--;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;WakeUp&lt;/span&gt;()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;_resetEvent&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Set&lt;/span&gt;();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;    }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;  Il metodo SleepingBroker.PlaceOrder ci permette di far durare la chiamata a PlaceOrder il tempo necessario   per creare una race condition.  Se il valore della property CallingPlaceOrderCount è maggiore di uno significa che più di un trade sta usando il Broker e  quindi il test deve fallire. &lt;/p&gt;
&lt;p&gt;  Proviamo a questo punto a scrivere il test: &lt;/p&gt;
&lt;div style="background: rgb(24, 24, 24) none repeat scroll 0% 0%; font-family: Consolas; font-size: 12pt; color: rgb(224, 224, 224); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;pre style="margin: 0px;"&gt;        [&lt;span style="color: rgb(199, 199, 241);"&gt;Test&lt;/span&gt;]&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;Access_To_The_Broker_Should_Be_Synchronized&lt;/span&gt;()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(199, 199, 241);"&gt;Order&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;order1&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;Order&lt;/span&gt;();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(199, 199, 241);"&gt;Order&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;order2&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;Order&lt;/span&gt;();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(199, 199, 241);"&gt;SleepingBroker&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;broker&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;SleepingBroker&lt;/span&gt;();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(199, 199, 241);"&gt;OrderThread&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;thread1&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;OrderThread&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;broker&lt;/span&gt;, &lt;span style="color: rgb(254, 241, 169);"&gt;order1&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(199, 199, 241);"&gt;OrderThread&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;thread2&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;OrderThread&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;broker&lt;/span&gt;, &lt;span style="color: rgb(254, 241, 169);"&gt;order2&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;thread1&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Start&lt;/span&gt;();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;thread2&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Start&lt;/span&gt;();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(199, 199, 241);"&gt;Assert&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;AreEqual&lt;/span&gt;(1, &lt;span style="color: rgb(254, 241, 169);"&gt;broker&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;CallingPlaceOrderCount&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;broker&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;WakeUp&lt;/span&gt;();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;  In questo test abbiamo creato due OrderThread che utilizzano lo stesso Broker (in questo caso SleepingBroker).  I due thread vengono fatti partire e controlliamo che effettivamente solo uno sia all'interno del metodo PlaceOrder. &lt;/p&gt;
&lt;p&gt;  Il test apparentemente corretto in realtà &lt;strong&gt;contiene un errore concettuale&lt;/strong&gt;. L'errore è che potrebbe fallire  o avere successo in maniera del tutto casuale perchè dipende dalla velocità di creazione ed esecuzione dei thread al momento  in cui si fa la Assert. &lt;/p&gt;
&lt;p&gt;  Il valore di CallingPlaceOrderCount potrebbe quindi essere 0, 1 oppure due. Zero nel caso in cui entrambi i thread siano  stati creati ma al momento della Assert la chiamata a PlaceOrder non sia ancora avvenuta. Uno nel caso che uno dei due  sia entrato nella PlaceOrder. Due nel caso in cui entrambi siano nella PlaceOrder. &lt;/p&gt;
&lt;p&gt;  Per come abbiamo scritto il test questo non è determinabile. Quindi modifichiamolo sincronizzandoci nel modo corretto.  Per far questo ci viene in aiuto la property &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.threadstate.aspx"&gt;ThreadState&lt;/a&gt;,  nel caso in cui il valore è impostato su WaitSleepJoin come descritto nella MSDN: &lt;/p&gt;
&lt;p&gt; &lt;cite&gt;The thread is blocked. This could be the result of calling Thread..::.Sleep or Thread..::.Join,  of requesting a lock — for example, by calling Monitor..::.Enter or Monitor..::.Wait — or of waiting on a thread  synchronization object such as ManualResetEvent. &lt;/cite&gt; &lt;/p&gt;
&lt;p&gt;  Quindi se entrambi i thread sono in WaitSleepJoin siamo sicuri di poter eseguire la Assert su CallingPlaceOrderCount  nel momento corretto. &lt;/p&gt;
&lt;p&gt;  Per controllare lo stato del thread Aggiungiamo la Property IsWaiting alla classe OrderThread. &lt;/p&gt;
&lt;div style="background: rgb(24, 24, 24) none repeat scroll 0% 0%; font-family: Consolas; font-size: 12pt; color: rgb(224, 224, 224); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;pre style="margin: 0px;"&gt;    &lt;span style="color: rgb(128, 128, 192);"&gt;class&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;OrderThread&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;    {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;IBroker&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;_broker&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;Order&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;_order&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;Thread&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;_thread&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;OrderThread&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;IBroker&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;broker&lt;/span&gt;, &lt;span style="color: rgb(199, 199, 241);"&gt;Order&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;order&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;_broker&lt;/span&gt; = &lt;span style="color: rgb(254, 241, 169);"&gt;broker&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;_order&lt;/span&gt; = &lt;span style="color: rgb(254, 241, 169);"&gt;order&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;bool&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;IsWaiting&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(128, 128, 192);"&gt;get&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;                &lt;span style="color: rgb(128, 128, 192);"&gt;if&lt;/span&gt; (&lt;span style="color: rgb(254, 241, 169);"&gt;_thread&lt;/span&gt; == &lt;span style="color: rgb(128, 128, 192);"&gt;null&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;                {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;                    &lt;span style="color: rgb(128, 128, 192);"&gt;return&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;false&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;                }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;                &lt;span style="color: rgb(128, 128, 192);"&gt;return&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;_thread&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;ThreadState&lt;/span&gt; == &lt;span style="color: rgb(199, 199, 241);"&gt;ThreadState&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;WaitSleepJoin&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;Start&lt;/span&gt;()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;_thread&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;Thread&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;PlaceOrder&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;_thread&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Start&lt;/span&gt;();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;PlaceOrder&lt;/span&gt;()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;_broker&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;PlaceOrder&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;_order&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;    }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;  Quindi ora aggiungiamo il codice nel test che attenda che per entrambi i Thread IsWaiting sia a true. &lt;/p&gt;
&lt;div style="background: rgb(24, 24, 24) none repeat scroll 0% 0%; font-family: Consolas; font-size: 12pt; color: rgb(224, 224, 224); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;pre style="margin: 0px;"&gt;        [&lt;span style="color: rgb(199, 199, 241);"&gt;Test&lt;/span&gt;]&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;Access_To_The_Broker_Should_Be_Synchronized&lt;/span&gt;()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(199, 199, 241);"&gt;Order&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;order1&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;Order&lt;/span&gt;();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(199, 199, 241);"&gt;Order&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;order2&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;Order&lt;/span&gt;();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(199, 199, 241);"&gt;SleepingBroker&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;broker&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;SleepingBroker&lt;/span&gt;();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(199, 199, 241);"&gt;OrderThread&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;thread1&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;OrderThread&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;broker&lt;/span&gt;, &lt;span style="color: rgb(254, 241, 169);"&gt;order1&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(199, 199, 241);"&gt;OrderThread&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;thread2&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;OrderThread&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;broker&lt;/span&gt;, &lt;span style="color: rgb(254, 241, 169);"&gt;order2&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;thread1&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Start&lt;/span&gt;();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;thread2&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Start&lt;/span&gt;();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(128, 128, 192);"&gt;while&lt;/span&gt;(!&lt;span style="color: rgb(254, 241, 169);"&gt;thread1&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;IsWaiting&lt;/span&gt; || !&lt;span style="color: rgb(254, 241, 169);"&gt;thread2&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;IsWaiting&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;                &lt;span style="color: rgb(199, 199, 241);"&gt;Thread&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Sleep&lt;/span&gt;(0);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(199, 199, 241);"&gt;Assert&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;AreEqual&lt;/span&gt;(1, &lt;span style="color: rgb(254, 241, 169);"&gt;broker&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;CallingPlaceOrderCount&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;broker&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;WakeUp&lt;/span&gt;();&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;     In questo modo abbiamo tolto l'elemento di casualità spiegato prima. Se non      modifichiamo il codice della classe OrderThread il test fallirà in modo      sistematico:&lt;/p&gt;
&lt;p style="font-family: 'Courier New',Courier,monospace;"&gt;         TestCase 'OrderThreadTests.Access_To_The_Broker_Should_Be_Synchronized' failed:          Equal assertion failed: [[1]]!=[[2]] &lt;/p&gt;
&lt;p&gt;  Aggiungiamo a questo punto la lock prima della chiamata di PlaceOrder nella classe OrderThread: &lt;/p&gt;
&lt;div style="background: rgb(24, 24, 24) none repeat scroll 0% 0%; font-family: Consolas; font-size: 12pt; color: rgb(224, 224, 224); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;pre style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;PlaceOrder&lt;/span&gt;()&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            &lt;span style="color: rgb(128, 128, 192);"&gt;lock&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;_broker&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            {&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;                &lt;span style="color: rgb(254, 241, 169);"&gt;_broker&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;PlaceOrder&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;_order&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;            }&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;        }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;  Proviamo ora a lanciare nuovamente il test ed ecco finalmente la conferma che i due thread sono  sincronizzati: &lt;/p&gt;
&lt;p&gt;     &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;Found 1 tests&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;[success] OrderThreadTests.Access_To_The_Broker_Should_Be_Synchronized     &lt;/span&gt; &lt;/p&gt;
&lt;p&gt;  Il motivo per cui il test passa è che in questo caso sono entrambi in waiting ma uno è all'interno del metodo     PlaceOrder mentre l'altro è fermo sulla lock. &lt;/p&gt;
&lt;p&gt;         L'esempio che ho fatto si può adattare facilmente anche ad altri scenari, in          quanto cambieranno gli attori, ma i concetti sono gli stessi.&lt;/p&gt;
&lt;p&gt;         Feedback?&lt;/p&gt;&lt;img src="http://blogs.ugidotnet.org/AntonioGanci/aggbug/93727.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Antonio Ganci</dc:creator>
            <guid>http://blogs.ugidotnet.org/AntonioGanci/archive/2008/08/17/93727.aspx</guid>
            <pubDate>Sun, 17 Aug 2008 10:46:26 GMT</pubDate>
            <wfw:comment>http://blogs.ugidotnet.org/AntonioGanci/comments/93727.aspx</wfw:comment>
            <comments>http://blogs.ugidotnet.org/AntonioGanci/archive/2008/08/17/93727.aspx#feedback</comments>
            <slash:comments>12</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/AntonioGanci/comments/commentRss/93727.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/AntonioGanci/services/trackbacks/93727.aspx</trackback:ping>
        </item>
        <item>
            <title>How I got Started in Software Development</title>
            <link>http://blogs.ugidotnet.org/AntonioGanci/archive/2008/07/17/93445.aspx</link>
            <description>Dopo la provocazione di &lt;a href="http://blogs.ugidotnet.org/ThinkingInGrava/archive/2008/07/16/how-i-got-started-in-software-development.aspx"&gt;Gianluca&lt;/a&gt; 	non potevo esimermi dal rispondere ;-).
&lt;p&gt; 		&lt;strong&gt;A quale età hai cominciato a programmare?&lt;/strong&gt; 	&lt;/p&gt;
&lt;p&gt; 		Quinta elementare: lessi un libro della casa editrice Jackson (qualcuno la ricorda?) la quale introduceva agli elementi di base sulla programmazione  	&lt;/p&gt;
&lt;p&gt; 		&lt;strong&gt; 			Come hai cominciato a programmare? 		&lt;/strong&gt; 	&lt;/p&gt;
&lt;p&gt; 		Su un foglio di carta. Scrivevo il listato rigorosamente in basic e poi lo simulavo manualmente. 	&lt;/p&gt;
&lt;p&gt; 		&lt;strong&gt; 			Qual’è stato il tuo primo linguaggio di programmazione? 		&lt;/strong&gt; 	&lt;/p&gt;
&lt;p&gt; 		Basic del Commdore64. 	&lt;/p&gt;
&lt;p&gt; 		&lt;strong&gt; 			Qual’è stato il primo programma vero che hai scritto? 		&lt;/strong&gt; 	&lt;/p&gt;
&lt;p&gt; 		Un gestionale in Foxpro per il mio professore di elettronica in quinta superiore. 	&lt;/p&gt;
&lt;p&gt; 		&lt;strong&gt; 			Quali linguaggi hai usato da quando hai cominciato a programmare? 		&lt;/strong&gt; 	&lt;/p&gt;
&lt;p&gt; 		Turbo Pascal, Basic (nelle varie incarnazioni GWBASIC, QuickBasic, ...), Assembler, C, C++, Prolog, VB, C# e tanti altri che nemmeno ricordo 	&lt;/p&gt;
&lt;p&gt; 		&lt;strong&gt; 			Quando è stato il tuo primo vero lavoro da programmatore? 		&lt;/strong&gt; 	&lt;/p&gt;
&lt;p&gt; 		Vedi sopra 	&lt;/p&gt;
&lt;p&gt; 		&lt;strong&gt; 			Con il senno di poi, rifaresti lo stesso il programmatore? Ricominceresti a programmare? 		&lt;/strong&gt; 	&lt;/p&gt;
&lt;p&gt; 		Certamente. What else? :-) 	&lt;/p&gt;
&lt;p&gt; 		&lt;strong&gt; 			Se ci fosse una cosa che hai imparato nella tua carriera e che vorresti dire ai giovani programmatori, cosa diresti? 		&lt;/strong&gt; 	&lt;/p&gt;
&lt;p&gt; 		Studiate, leggete e soprattutto imparate dal codice scritto da altri. Un'ultima cosa è grazie ai clienti se pagate l'affitto quindi 		non trattateli troppo male. 	&lt;/p&gt;
&lt;p&gt; 		&lt;strong&gt; 			Qual’è la cosa più divertente che hai programmato? 		&lt;/strong&gt; 	&lt;/p&gt;
&lt;p&gt; 		Alcuni videogiochi realizzati con il mitico &lt;a href="http://en.wikipedia.org/wiki/Shoot%27Em-Up_Construction_Kit"&gt;S.E.U.C.K.&lt;/a&gt; (anche se non si può dire verà programmazione) 		e la gestione multiplayer di un videogioco tramite le DirectPlay 	&lt;/p&gt;
&lt;p&gt; 		Chi tirare in ballo ora? 	&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.ugidotnet.org/papo/Default.aspx"&gt;Papo&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.ugidotnet.org/Royv/Default.aspx"&gt;Roberto Valenti&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.ugidotnet.org/PierreGreborio/Default.aspx"&gt;Pierre Greborio&lt;/a&gt;&lt;/p&gt;
&lt;a href="http://blogs.ugidotnet.org/PierreGreborio/Default.aspx"&gt;	&lt;/a&gt;
&lt;p&gt;&lt;a href="http://blogs.ugidotnet.org/rosalba/Default.aspx"&gt;Rosalba Fiore&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.ugidotnet.org/AntonioGanci/aggbug/93445.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Antonio Ganci</dc:creator>
            <guid>http://blogs.ugidotnet.org/AntonioGanci/archive/2008/07/17/93445.aspx</guid>
            <pubDate>Thu, 17 Jul 2008 20:36:48 GMT</pubDate>
            <wfw:comment>http://blogs.ugidotnet.org/AntonioGanci/comments/93445.aspx</wfw:comment>
            <comments>http://blogs.ugidotnet.org/AntonioGanci/archive/2008/07/17/93445.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/AntonioGanci/comments/commentRss/93445.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/AntonioGanci/services/trackbacks/93445.aspx</trackback:ping>
        </item>
        <item>
            <title>Tell, Don't Ask - alcuni spunti di riflessioni su come migliorare il disegno delle proprie applicazioni</title>
            <link>http://blogs.ugidotnet.org/AntonioGanci/archive/2008/07/17/93444.aspx</link>
            <description>&lt;p&gt; 		Ho letto il post &lt;a href="http://michaelfeathers.typepad.com/michael_feathers_blog/2008/06/the-flawed-theo.html"&gt;The Flawed Theory Behind Unit Testing&lt;/a&gt; 		di Michael Feathers e mi ha fornito alcuni spunti interessanti di riflessione. In particolare: 	&lt;/p&gt;
&lt;p&gt; 		&lt;cite&gt; 			John Nolan, gave his developers a challenge: write OO code with no getters.  Whenever possible, tell another object to do something rather than ask.   			In the process of doing this, they noticed that their code became supple and easy to change. 		&lt;/cite&gt; 	&lt;/p&gt;
&lt;p&gt; 		Ho rivolto la questione al team con cui sto lavorando ed il &lt;a href="http://matteo.vaccari.name/blog/"&gt;coach&lt;/a&gt; ha posto la seguente domanda: 	&lt;/p&gt;
&lt;p&gt; 		&lt;cite&gt; 			Una cosa che continuo a chiedermi a proposito dell "tell, don't ask" è la maniera in cui vengono normalmente realizzate le pagine web: tu hai un template a cui passi oggetti a cui chiedi varie informazioni.  E' tutto un "ask, don't tell", che fa sì che gli oggetti che passi alla view siano, alla fine, oggetti di dominio, i quali finiscono per essere poco più che contenitori di dati estratti dal DB.  Questo è quello che si fa di solito.  La domanda che vi pongo è: come si potrebbe fare altrimenti?  A partire dalla view: come puoi fare una view che applica il "tell, don't ask"? 		&lt;/cite&gt; 	&lt;/p&gt;
&lt;p&gt; 		Un altro link interessante su questo concetto è &lt;a href="http://pragprog.com/articles/tell-dont-ask"&gt;Tell, Don't Ask&lt;/a&gt;. 	&lt;/p&gt;
&lt;p&gt; 		Alla domanda di prima non ho una risposta, ma ci sto riflettendo. Inoltre voglio approfondire l'argomento e verificare se l'approccio è efficace. 		Questo implica ragionare con gli oggetti in funzione di cosa &lt;em&gt;fanno&lt;/em&gt; piuttosto che dipendere da quale stato siano. 	&lt;/p&gt;
&lt;p&gt; 		In termini di TDD significa prediligere i test d'interazione piuttosto che quelli di stato e quindi l'utilizzo intensivo dei mock objects. 	&lt;/p&gt;
&lt;p&gt; 		Cosa ne pensate? 	&lt;/p&gt;&lt;img src="http://blogs.ugidotnet.org/AntonioGanci/aggbug/93444.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Antonio Ganci</dc:creator>
            <guid>http://blogs.ugidotnet.org/AntonioGanci/archive/2008/07/17/93444.aspx</guid>
            <pubDate>Thu, 17 Jul 2008 20:00:02 GMT</pubDate>
            <wfw:comment>http://blogs.ugidotnet.org/AntonioGanci/comments/93444.aspx</wfw:comment>
            <comments>http://blogs.ugidotnet.org/AntonioGanci/archive/2008/07/17/93444.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/AntonioGanci/comments/commentRss/93444.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/AntonioGanci/services/trackbacks/93444.aspx</trackback:ping>
        </item>
        <item>
            <title>Fino a che punto siamo disposti a cambiare nel lavoro?</title>
            <link>http://blogs.ugidotnet.org/AntonioGanci/archive/2008/06/18/93085.aspx</link>
            <description>A parole tutti vorremmo &lt;span style="font-style: italic;"&gt;cambiare&lt;/span&gt;, è un mantra, che spesso si sente in tv soprattutto in periodo elettorale. Sembrerebbe che la natura umana stia a suo agio nel cambiamento.&lt;br /&gt;
In realtà le cose funzionano in maniera completamente diversa, &lt;span style="font-weight: bold;"&gt;noi per natura, non vogliamo cambiare; il cambiamento ci costa fatica e per istinto cerchiamo di osteggiarlo&lt;/span&gt;.&lt;br /&gt;
Riportando queste divagazioni al nostro mestiere di sviluppatori, magari con qualche anno di lavoro alle spalle, proviamo a rispondere alla domanda: Fino a che punto siamo disposti a cambiare? E con cambiare intendo:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
    &lt;li&gt;Metodo di approccio allo sviluppo software (ad es: passare da Waterfall ad xp? e viceversa?)&lt;/li&gt;
    &lt;li&gt;Tecnologia (sviluppo da diversi anni in .NET passerei a java? e viceversa?)&lt;/li&gt;
    &lt;li&gt;Sistema Operativo (ho sempre usato windows xp, passerei a Vista e a linux? e viceversa?)&lt;/li&gt;
    &lt;li&gt;Altro?&lt;/li&gt;
&lt;/ul&gt;
Quale la cosa che non cambierei per nulla al mondo? (a meno di eventi che ci costringano senza alternative).&lt;br /&gt;
&lt;br /&gt;
A questo proposito segnalo l'interessante post sul &lt;a href="http://blogs.msdn.com/eric_brechner/archive/2008/03/01/things-have-got-to-change-change-management.aspx"&gt;cambiamento&lt;/a&gt; che aveva segnalato lorenzo in questo &lt;a href="http://blogs.ugidotnet.org/lbarbieri/archive/2008/03/01/91457.aspx"&gt;post&lt;/a&gt; e che in parte ha ispirato questo post.&lt;br /&gt;
Cosa ne pensate?&lt;img src="http://blogs.ugidotnet.org/AntonioGanci/aggbug/93085.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Antonio Ganci</dc:creator>
            <guid>http://blogs.ugidotnet.org/AntonioGanci/archive/2008/06/18/93085.aspx</guid>
            <pubDate>Wed, 18 Jun 2008 13:05:51 GMT</pubDate>
            <wfw:comment>http://blogs.ugidotnet.org/AntonioGanci/comments/93085.aspx</wfw:comment>
            <comments>http://blogs.ugidotnet.org/AntonioGanci/archive/2008/06/18/93085.aspx#feedback</comments>
            <slash:comments>7</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/AntonioGanci/comments/commentRss/93085.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/AntonioGanci/services/trackbacks/93085.aspx</trackback:ping>
        </item>
        <item>
            <title>Object-Oriented Reengineering Patterns</title>
            <link>http://blogs.ugidotnet.org/AntonioGanci/archive/2008/06/09/92985.aspx</link>
            <description>&lt;p&gt;Segnalo il libro &lt;a href="http://www.iam.unibe.ch/~scg/OORP/"&gt;Object-Oriented Reengineering Patterns&lt;/a&gt; scaricabile  gratuitamente come pdf.  &lt;/p&gt;
&lt;p&gt;   Non ne ho ancora terminato la lettura, ma per ora mi ha fornito alcuni spunti interessanti.  &lt;/p&gt;
&lt;p&gt;   Affronta il problema di reingegnerizzare un software esistente e fornisce come strumenti una serie di pattern.  &lt;/p&gt;&lt;img src="http://blogs.ugidotnet.org/AntonioGanci/aggbug/92985.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Antonio Ganci</dc:creator>
            <guid>http://blogs.ugidotnet.org/AntonioGanci/archive/2008/06/09/92985.aspx</guid>
            <pubDate>Mon, 09 Jun 2008 18:18:34 GMT</pubDate>
            <wfw:comment>http://blogs.ugidotnet.org/AntonioGanci/comments/92985.aspx</wfw:comment>
            <comments>http://blogs.ugidotnet.org/AntonioGanci/archive/2008/06/09/92985.aspx#feedback</comments>
            <slash:comments>7</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/AntonioGanci/comments/commentRss/92985.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/AntonioGanci/services/trackbacks/92985.aspx</trackback:ping>
        </item>
        <item>
            <title>Usare il Test Driven Development per progettare applicazioni multithreading - Un esempio concreto</title>
            <category>Extreme Programming</category>
            <link>http://blogs.ugidotnet.org/AntonioGanci/archive/2008/06/06/92951.aspx</link>
            <description>&lt;p&gt;   Il multithreading aggiunge complessità al design di un'applicazione.      Occorre prestare attenzione alle differenti problematiche legate alla       sincronizzazione, race condition, ecc.&lt;/p&gt;
&lt;p&gt;   In questi giorni sto realizzando un'applicazione in cui devo salvare dei messaggi di log    su un database e per non rallentare il chiamante la scrittura sul database avviene in modo   asincrono.  &lt;/p&gt;
&lt;p&gt;   Voglio realizzare questa funzionalità in       &lt;a href="http://en.wikipedia.org/wiki/Test-driven_development"&gt;TDD&lt;/a&gt; e riporto qui i passi che ho effettuato e la soluzione   trovata. Per ogni test scriverò prima il codice del test, introducendo classi e metodi necessari a       descrivere lo scenario che sto testando, successivamente scriverò       l'implementazione minima per far compilare il test ed infine modificherò il       codice per farlo passare.&lt;/p&gt;
&lt;p&gt;   Partiamo dal LogWriter:  &lt;/p&gt;
&lt;div style="background: rgb(24, 24, 24) none repeat scroll 0% 50%; font-family: Consolas; font-size: 12pt; color: rgb(224, 224, 224); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;p style="margin: 0px;"&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;interface&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;ILogWriter&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     &lt;span style="color: rgb(128, 128, 192);"&gt;void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;Write&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;Log&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;log&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;     L'implementazione concreta di questa interfaccia salva sul database i dati contenuti      nella classe Log.  La classe che realizzerò in TDD deve chiamare in modo asincrono il metodo Write. &lt;/p&gt;
&lt;p&gt;     Non utilizzerò librerie di mocking e scriverò delle classi         &lt;a href="http://martinfowler.com/articles/mocksArentStubs.html"&gt;stub&lt;/a&gt; che      simuleranno i vari scenari da testare; questo renderà più semplice      la comprensione del codice. Il primo stub che useremo conta quante      volte viene chiamato il metodo Write e salva l'ultimo parametro con cui è stato      chiamato:&lt;/p&gt;
&lt;div style="background: rgb(24, 24, 24) none repeat scroll 0% 50%; font-family: Consolas; font-size: 12pt; color: rgb(224, 224, 224); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(128, 128, 192);"&gt;class&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;LogWriterForTest&lt;/span&gt; : &lt;span style="color: rgb(199, 199, 241);"&gt;ILogWriter&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;int&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;WriteCallCount&lt;/span&gt; = 0;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;Log&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;Log&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;null&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;Write&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;Log&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;log&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(254, 241, 169);"&gt;WriteCallCount&lt;/span&gt;++;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(254, 241, 169);"&gt;Log&lt;/span&gt; = &lt;span style="color: rgb(254, 241, 169);"&gt;log&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;
&lt;/div&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;Il test controlla che quando viene accodato un log              viene chiamato il metodo Write:&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;div style="background: rgb(24, 24, 24) none repeat scroll 0% 50%; font-family: Consolas; font-size: 12pt; color: rgb(224, 224, 224); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;[&lt;span style="color: rgb(199, 199, 241);"&gt;Test&lt;/span&gt;]&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;When_Enqueue_A_Log_The_LogWriter_Is_Invoked&lt;/span&gt;()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(199, 199, 241);"&gt;Log&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;log&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;Log&lt;/span&gt;();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(199, 199, 241);"&gt;LogWriterForTest&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;LogWriterForTest&lt;/span&gt;();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(199, 199, 241);"&gt;LogThread&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;thread&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;LogThread&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(254, 241, 169);"&gt;thread&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Enqueue&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;log&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(199, 199, 241);"&gt;Assert&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;AreEqual&lt;/span&gt;(1, &lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;WriteCallCount&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(199, 199, 241);"&gt;Assert&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;AreEqual&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;log&lt;/span&gt;, &lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Log&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;
&lt;/div&gt;
&lt;p style="margin: 0px;"&gt;          &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;         Per far passare il test non è necessario che il metodo Enqueue chiami il metodo          Write in modo asincrono, questo sarà compito del prossimo test. Questo concetto          è importante nel TDD e lo ribadisco: &lt;strong&gt;scrivere solo il codice indispensabile a          far passare il test anche se non contiene ancora le funzionalità che          effettivamente ci servono&lt;/strong&gt;. Questo ci consente di ridurre al minimo la          complessità del codice e dell'architettura e di arrivare alla soluzione in modo          incrementale.      &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;         Il primo passo da fare ora è quello di scrivere il codice minimo per compilare,          ma che non basta per far passare il test:&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;      &lt;/p&gt;
&lt;div style="background: rgb(24, 24, 24) none repeat scroll 0% 50%; font-family: Consolas; font-size: 12pt; color: rgb(224, 224, 224); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;p style="margin: 0px;"&gt;             &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;class&lt;/span&gt;             &lt;span style="color: rgb(199, 199, 241);"&gt;LogThread&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;             {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;             LogThread&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;ILogWriter&lt;/span&gt;             &lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;              &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;             void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;Enqueue&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;Log&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;log&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;             }&lt;/p&gt;
&lt;/div&gt;
&lt;p style="margin: 0px;"&gt;      &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;         Se eseguo ora il test ottengo il messaggio: Expected: 1 But was: 0, in quanto          il metodo Write non è stato chiamato; aggiungiamo quindi la chiamata:&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;          &lt;/p&gt;
&lt;div style="background: rgb(24, 24, 24) none repeat scroll 0% 50%; font-family: Consolas; font-size: 12pt; color: rgb(224, 224, 224); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;p style="margin: 0px;"&gt;             &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;class&lt;/span&gt;             &lt;span style="color: rgb(199, 199, 241);"&gt;LogThread&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;             {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     &lt;span style="color: rgb(128, 128, 192);"&gt;private&lt;/span&gt;             &lt;span style="color: rgb(128, 128, 192);"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;             ILogWriter&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;_writer&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;              &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;             LogThread&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;ILogWriter&lt;/span&gt;             &lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;         &lt;span style="color: rgb(254, 241, 169);"&gt;_writer&lt;/span&gt; =             &lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;              &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;             void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;Enqueue&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;Log&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;log&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;         &lt;span style="color: rgb(254, 241, 169);"&gt;_writer&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Write&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;log&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;             }&lt;/p&gt;
&lt;/div&gt;
&lt;p style="margin: 0px;"&gt;      &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     Rilanciamo il test che passa con successo.&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     Passiamo al prossimo scenario: quando viene chiamata la Write il metodo Enqueue      la esegue in modo asincrono. Ci serve un meccanismo di sincronizzazione che ci      permetta di bloccare il metodo write e sbloccarlo successivamente con un      comando; creiamo a questo scopo un nuovo stub:&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;      &lt;/p&gt;
&lt;div style="background: rgb(24, 24, 24) none repeat scroll 0% 50%; font-family: Consolas; font-size: 12pt; color: rgb(224, 224, 224); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;p style="margin: 0px;"&gt;         &lt;span style="color: rgb(128, 128, 192);"&gt;class&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;             ManualResetLogWriter&lt;/span&gt; : &lt;span style="color: rgb(199, 199, 241);"&gt;ILogWriter&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;             {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;             int&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;WritingCount&lt;/span&gt; = 0;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;             Log&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;Log&lt;/span&gt; =             &lt;span style="color: rgb(128, 128, 192);"&gt;null&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;             readonly&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;ManualResetEvent&lt;/span&gt;             &lt;span style="color: rgb(254, 241, 169);"&gt;ResetEvent&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;             new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;ManualResetEvent&lt;/span&gt;(&lt;span style="color: rgb(128, 128, 192);"&gt;false&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;             void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;Write&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;Log&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;log&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;         &lt;span style="color: rgb(254, 241, 169);"&gt;WritingCount&lt;/span&gt;++;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;         &lt;span style="color: rgb(254, 241, 169);"&gt;Log&lt;/span&gt; =             &lt;span style="color: rgb(254, 241, 169);"&gt;log&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;         &lt;span style="color: rgb(254, 241, 169);"&gt;ResetEvent&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;WaitOne&lt;/span&gt;();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                &lt;span class="style1"&gt; WritingCount--;&lt;/span&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;             }&lt;/p&gt;
&lt;/div&gt;
&lt;p style="margin: 0px;"&gt;              &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;             Quando chiamiamo il metodo Write del ManualResetLogWriter l'esecuzione si blocca              sull'istruzione ResetEvent.WaitOne() fin quando da un altro thread non viene              chiamato il metodo Set della classe del framework .NET             &lt;a href="http://msdn.microsoft.com/it-it/library/system.threading.manualresetevent(VS.80).aspx"&gt;ManualResetEvent&lt;/a&gt;.&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;             La classe ManualResetLogWriter è utile nel prossimo test, in cui voglio              verificare che le chiamate al metodo Write avvengono in modo asincrono. Sarà              necessario modificare il metodo Enqueue affinché invochi il metodo write in un              theread dedicato, evitando così che l'esecuzione dell'Enqueue si blocchi              sull'istruzione WaitOne. Verifichiamolo:&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;              &lt;/p&gt;
&lt;div style="background: rgb(24, 24, 24) none repeat scroll 0% 50%; font-family: Consolas; font-size: 12pt; color: rgb(224, 224, 224); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;p style="margin: 0px;"&gt;             [&lt;span style="color: rgb(199, 199, 241);"&gt;Test&lt;/span&gt;]&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;             &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;void&lt;/span&gt;             &lt;span style="color: rgb(254, 241, 169);"&gt;The_Calls_To_The_Writer_Are_Asynchronous&lt;/span&gt;()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;             {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     &lt;span style="color: rgb(199, 199, 241);"&gt;Log&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;             log&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt;             &lt;span style="color: rgb(199, 199, 241);"&gt;Log&lt;/span&gt;();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     &lt;span style="color: rgb(199, 199, 241);"&gt;ManualResetLogWriter&lt;/span&gt;             &lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt;             &lt;span style="color: rgb(199, 199, 241);"&gt;ManualResetLogWriter&lt;/span&gt;();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     &lt;span style="color: rgb(199, 199, 241);"&gt;LogThread&lt;/span&gt;             &lt;span style="color: rgb(254, 241, 169);"&gt;thread&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt;             &lt;span style="color: rgb(199, 199, 241);"&gt;LogThread&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     &lt;span style="color: rgb(254, 241, 169);"&gt;thread&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Enqueue&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;log&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(128, 128, 192);"&gt;while&lt;/span&gt;&lt;span style="color: rgb(254, 241, 169);"&gt;&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;WriteCallCount &lt;/span&gt;&lt;span style="color: rgb(254, 241, 169);"&gt;&lt;/span&gt;&lt;span style="color: rgb(254, 241, 169);"&gt;&lt;/span&gt;== 0&lt;span style="color: rgb(254, 241, 169);"&gt;&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;       &lt;span style="color: rgb(199, 199, 241);"&gt;Thread&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Sleep&lt;/span&gt;(0);  &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    }&lt;br /&gt;
&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     &lt;span style="color: rgb(199, 199, 241);"&gt;Assert&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;AreEqual&lt;/span&gt;(1, &lt;span style="color: rgb(254, 241, 169);"&gt;             writer&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;WriteCallCount&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;ResetEvent&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Set&lt;/span&gt;();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(199, 199, 241);"&gt;Assert&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;AreEqual&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;log&lt;/span&gt;,             &lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Log&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;             }&lt;/p&gt;
&lt;/div&gt;
&lt;p style="margin: 0px;"&gt;      &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;     Se eseguiamo il test con l'implementazione attuale della Enqueue vediamo che il      test si blocca sull'istruzione: thread.Enqueue(log). Modifichiamo il codice in modo da far passare questo      secondo test:&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;          &lt;/p&gt;
&lt;div style="background: rgb(24, 24, 24) none repeat scroll 0% 50%; font-family: Consolas; font-size: 12pt; color: rgb(224, 224, 224); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;class&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;LogThread&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(128, 128, 192);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;ILogWriter&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;_writer&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;LogThread&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;ILogWriter&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(254, 241, 169);"&gt;_writer&lt;/span&gt; = &lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;   &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;Enqueue&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;Log&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;log&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(199, 199, 241);"&gt;Thread&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;thread&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;Thread&lt;/span&gt;(&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;delegate&lt;/span&gt;()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;_writer&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Write&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;log&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        });&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(254, 241, 169);"&gt;thread&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Start&lt;/span&gt;();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;
&lt;/div&gt;
&lt;p style="margin: 0px;"&gt;          &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;         Per maggiore compattezza del codice la chiamata _writer.Write(log) è stata fatta          all'interno di un         &lt;a href="http://msdn.microsoft.com/en-us/library/0yw3tz5k(VS.80).aspx"&gt;anonymous          method&lt;/a&gt;.&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;          Rieseguiamo il test che ora passa. &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                 Chiaramente non abbiamo ancora finito, perchè due          thread in contemporanea potrebbero eseguire la Write creando una         &lt;a href="http://it.wikipedia.org/wiki/Race_condition"&gt;Race Condition&lt;/a&gt; (o          corsa critica in italiano).&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;         Il prossimo test si occuperà proprio di testare che non ci sia una race          condition, cioè dobbiamo creare uno scenario in cui il test fallisce          nel caso in cui più thread eseguono contemporaneamente il metodo Write. Scriviamo il          test e poi commentiamolo un pezzo per volta:&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;          &lt;/p&gt;
&lt;div style="background: rgb(24, 24, 24) none repeat scroll 0% 50%; font-family: Consolas; font-size: 12pt; color: rgb(224, 224, 224); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;p style="margin: 0px;"&gt;[&lt;span style="color: rgb(199, 199, 241);"&gt;Test&lt;/span&gt;]&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;Two_Logs_Enqueued_Are_Served_One_At_Time&lt;/span&gt;()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(199, 199, 241);"&gt;ManualResetLogWriter&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;ManualResetLogWriter&lt;/span&gt;();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(199, 199, 241);"&gt;LogThread&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;thread&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;LogThread&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(199, 199, 241);"&gt;Log&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;log1&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;Log&lt;/span&gt;();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(254, 241, 169);"&gt;thread&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Enqueue&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;log1&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(128, 128, 192);"&gt;while&lt;/span&gt; (&lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;WritingCount&lt;/span&gt; &amp;lt; 1)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(199, 199, 241);"&gt;Thread&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Sleep&lt;/span&gt;(0);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(199, 199, 241);"&gt;Log&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;log2&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;Log&lt;/span&gt;();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(254, 241, 169);"&gt;thread&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Enqueue&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;log2&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(128, 128, 192);"&gt;while&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;thread&lt;/span&gt;.&lt;span class="style1"&gt;RunningThreadCount&lt;/span&gt; &amp;lt; 2)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(199, 199, 241);"&gt;Thread&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Sleep&lt;/span&gt;(0);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(199, 199, 241);"&gt;Assert&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;AreEqual&lt;/span&gt;(1, &lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;WritingCount&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;ResetEvent&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Set&lt;/span&gt;();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(128, 128, 192);"&gt;while&lt;/span&gt; (&lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;WritingCount&lt;/span&gt; &amp;gt; 0)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(199, 199, 241);"&gt;Thread&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Sleep&lt;/span&gt;(0);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;
&lt;/div&gt;
&lt;p style="margin: 0px;"&gt;          &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;         Nel codice del test precedente ho usato più volte la chiamata Thread.Sleep(0),          il metodo Sleep interrompe il thread corrente per x millisecondi, se invece          viene passato zero si permette al thread corrente di essere sospeso; questo per          evitare di bloccare il PC con CPU al 100% nel caso in cui il test si blocchi in          uno dei cicli while.&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;          &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;         Il primo ciclo while attende che il primo thread sia fermo all'istruzione          ResetEvent.WaitOne del ManualResetLogWriter.&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;          &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;         Viene successivamente accodato il secondo log (variabile log2); ci serve quindi          un meccanismo che mi permetta di verificare che i thread in esecuzione siano          effettivamente due. Per questo scopo introduciamo, per ora solo nel codice del test, la          property RunningThreadCount ed aspettiamo che raggiunga il valore 2.&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;          &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;         Segue la Assert la quale assume che ci sia un solo thread in scrittura mentra          l'altro è in attesa (ricordo che lo scopo é quello di far si che il metodo          Write venga eseguito in mutua esclusione).&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;          &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;         Il test termina sbloccando la Write tramite l'istruzione writer.ResetEvent.Set()          ed infine attendiamo che entrambi i thread siano terminati.&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;          &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;         Aggiungiamo la property RunningThreadCount alla classe LogThread:&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;          &lt;/p&gt;
&lt;div style="background: rgb(24, 24, 24) none repeat scroll 0% 50%; font-family: Consolas; font-size: 12pt; color: rgb(224, 224, 224); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;class&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;LogThread&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(128, 128, 192);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;ILogWriter&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;_writer&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(128, 128, 192);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;int&lt;/span&gt;     &lt;span style="color: rgb(254, 241, 169);"&gt;_&lt;span class="style1"&gt;runningThreadCount&lt;/span&gt;&lt;/span&gt; = 0;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;LogThread&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;ILogWriter&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(254, 241, 169);"&gt;_writer&lt;/span&gt; = &lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;int&lt;/span&gt;     &lt;span class="style1"&gt;RunningThreadCount&lt;/span&gt; { &lt;span style="color: rgb(128, 128, 192);"&gt;get&lt;/span&gt; { &lt;span style="color: rgb(128, 128, 192);"&gt;return&lt;/span&gt;     &lt;span style="color: rgb(254, 241, 169);"&gt;_&lt;/span&gt;&lt;span class="style1"&gt;runningThreadCount&lt;/span&gt;; } }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;Enqueue&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;Log&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;log&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(199, 199, 241);"&gt;Thread&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;thread&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;Thread&lt;/span&gt;(&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;delegate&lt;/span&gt;()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                 &lt;span class="style1"&gt;_runningThreadCount&lt;/span&gt;++;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;_writer&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Write&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;log&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                 &lt;span class="style1"&gt;_runningThreadCount&lt;/span&gt;--;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        });&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(254, 241, 169);"&gt;thread&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Start&lt;/span&gt;();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;
&lt;/div&gt;
&lt;p style="margin: 0px;"&gt;          &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;         Eseguendo il test si nota che la assert fallisce in quanto tutte e due i          thread eseguono il metodo Write. Dobbiamo ora inserire un meccanismo di          sincronizzazione, useremo l'istruzione lock:&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;          &lt;/p&gt;
&lt;div style="background: rgb(24, 24, 24) none repeat scroll 0% 50%; font-family: Consolas; font-size: 12pt; color: rgb(224, 224, 224); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;Enqueue&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;Log&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;log&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(199, 199, 241);"&gt;Thread&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;thread&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;Thread&lt;/span&gt;(&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;delegate&lt;/span&gt;()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                 &lt;span class="style1"&gt;_runningThreadCount&lt;/span&gt;++;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(128, 128, 192);"&gt;lock&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;_writer&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                &lt;span style="color: rgb(254, 241, 169);"&gt;_writer&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Write&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;log&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                 &lt;span class="style1"&gt;_runningThreadCount&lt;/span&gt;--;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        });&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(254, 241, 169);"&gt;thread&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Start&lt;/span&gt;();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p style="margin: 0px;"&gt;          &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;         Ora rilanciamo il test il quale passerà con successo.&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;         &lt;em&gt;A qualcuno potrà sembrare strano che sia stata aggiunta la property          RunningThreadCount, in quanto viene usata solo dal test. Questa pratica però è          piuttosto comune nel TDD e capita spesso che queste funzionalità, aggiunte solo          per poter testare la classe, tornino utili in seguito anche nel codice di          produzione.&lt;/em&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;          &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;         Se il metodo Write sollevasse un'eccezione la property RunningThreadCount non verrebbe          decrementata. Creiamo un nuovo stub il quale sollevi un eccezione:&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;          &lt;/p&gt;
&lt;div style="background: rgb(24, 24, 24) none repeat scroll 0% 50%; font-family: Consolas; font-size: 12pt; color: rgb(224, 224, 224); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(128, 128, 192);"&gt;class &lt;/span&gt;&lt;span style="color: rgb(199, 199, 241);"&gt;ExceptionRaiseLogWriter&lt;/span&gt; : &lt;span style="color: rgb(199, 199, 241);"&gt;ILogWriter&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;bool&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;IsWriting&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;false&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;Write&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;Log&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;log&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(254, 241, 169);"&gt;IsWriting&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;true&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;throw&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;ArgumentException&lt;/span&gt;();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;
&lt;/div&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;Ed il test che verifichi che effettivamente venga              descrementata la property:&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;div style="background: rgb(24, 24, 24) none repeat scroll 0% 50%; font-family: Consolas; font-size: 12pt; color: rgb(224, 224, 224); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;When_The_Writer_Throws_An_Exception_The_QueueLength_Is_Decreased&lt;/span&gt;()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(199, 199, 241);"&gt;ExceptionRaiseLogWriter&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;ExceptionRaiseLogWriter&lt;/span&gt;();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(199, 199, 241);"&gt;LogThread&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;thread&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;LogThread&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(254, 241, 169);"&gt;thread&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Enqueue&lt;/span&gt;(&lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;Log&lt;/span&gt;());&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(128, 128, 192);"&gt;while&lt;/span&gt;(!&lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;IsWriting&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(199, 199, 241);"&gt;Thread&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Sleep&lt;/span&gt;(0);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(128, 128, 192);"&gt;while&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;thread&lt;/span&gt;.&lt;span class="style1"&gt;RunningThreadCount&lt;/span&gt; &amp;gt; 0)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(199, 199, 241);"&gt;Thread&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Sleep&lt;/span&gt;(0);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;
&lt;/div&gt;
&lt;p style="margin: 0px;"&gt;          &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;         Proviamo ad eseguirlo: il test si blocca all'interno          dell'ultimo while.&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;         Per far passare il test aggiungiamo un try / finally al metodo Enqueue della          classe LogThread:&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;          &lt;/p&gt;
&lt;div style="background: rgb(24, 24, 24) none repeat scroll 0% 50%; font-family: Consolas; font-size: 12pt; color: rgb(224, 224, 224); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;Enqueue&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;Log&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;log&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(199, 199, 241);"&gt;Thread&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;thread&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;Thread&lt;/span&gt;(&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(128, 128, 192);"&gt;delegate&lt;/span&gt;()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                      &lt;span class="style1"&gt;_runningThreadCount&lt;/span&gt;++;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                &lt;span style="color: rgb(128, 128, 192);"&gt;try&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                    &lt;span style="color: rgb(128, 128, 192);"&gt;lock&lt;/span&gt; (&lt;span style="color: rgb(254, 241, 169);"&gt;_writer&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                    {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                        &lt;span style="color: rgb(254, 241, 169);"&gt;_writer&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Write&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;log&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                    }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                &lt;span style="color: rgb(128, 128, 192);"&gt;finally&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                          &lt;span class="style1"&gt;_runningThreadCount&lt;/span&gt;--;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            });&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;thread&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Start&lt;/span&gt;();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        }&lt;/p&gt;
&lt;/div&gt;
&lt;p style="margin: 0px;"&gt;          &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;         A questo punto anche questo test è a posto. &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;         Mancano ancora altre cose, come la          gestione delle eccezioni, ecc. ma credo che il modo di procedere ora sia chiaro. &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;         Un altro test interessante da sviluppare è quello relativo alla gestione delle          richieste secondo una politica &lt;a href="http://it.wikipedia.org/wiki/FIFO"&gt;FIFO&lt;/a&gt;          mediante una coda, vale a dire che la          prima richiesta accodata sia effettivamente la prima ad essere eseguita, mentre          nell'implentazione derivata dai test finora scritti l'ordine di scrittura          dipende da quale thread viene sbloccato prima e quindi non è deterministico.&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;         Se avete suggerimenti, consigli o segnalazioni di errori scrivetemeli nei          commenti.&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;          &lt;/p&gt;&lt;img src="http://blogs.ugidotnet.org/AntonioGanci/aggbug/92951.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Antonio Ganci</dc:creator>
            <guid>http://blogs.ugidotnet.org/AntonioGanci/archive/2008/06/06/92951.aspx</guid>
            <pubDate>Fri, 06 Jun 2008 11:29:09 GMT</pubDate>
            <wfw:comment>http://blogs.ugidotnet.org/AntonioGanci/comments/92951.aspx</wfw:comment>
            <comments>http://blogs.ugidotnet.org/AntonioGanci/archive/2008/06/06/92951.aspx#feedback</comments>
            <slash:comments>14</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/AntonioGanci/comments/commentRss/92951.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/AntonioGanci/services/trackbacks/92951.aspx</trackback:ping>
        </item>
        <item>
            <title>Esempio di codice per generare un pdf tramite la libreria ITextSharp</title>
            <category>Tips</category>
            <link>http://blogs.ugidotnet.org/AntonioGanci/archive/2008/06/04/92915.aspx</link>
            <description>&lt;p&gt;   In questi giorni un mio amico mi ha chiesto un softwarino    (chissà perchè quando si chiede un favore si usa il diminutivo &lt;img src="/Providers/BlogEntryEditor/FCKeditor/editor/images/smiley/msn/wink_smile.gif" alt="" /&gt;) che partendo da una tabella di Access   generasse una serie di Moduli F24 compilati.  &lt;/p&gt;
&lt;p&gt;   Il modulo dell'F24 da compilare si può    &lt;a href="http://www.agenziaentrate.it/ilwwcm/connect/Nsi/Strumenti/Modulistica/Versamenti/modello+f24/"&gt;scaricare&lt;/a&gt;   dal sito dell' &lt;a href="http://www.agenziaentrate.it"&gt;agenzia delle entrate&lt;/a&gt;  &lt;/p&gt;
&lt;p&gt;   A questo punto mi manca una libreria, possibilmente open source, per aggiungere le informazioni necessarie.  &lt;/p&gt;
&lt;p&gt;   Dopo un paio di ricerche ho provato &lt;a href="http://sourceforge.net/projects/itextsharp/"&gt;iTextSharp&lt;/a&gt; porting della   libreria Java iText  &lt;/p&gt;
&lt;p&gt;   Riporto una parte del codice che ho scritto per la generazione del pdf:  &lt;/p&gt;
&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red224\green224\blue224;\red24\green24\blue24;\red128\green128\blue192;\red199\green199\blue241;\red254\green241\blue169;\red96\green255\blue96;}??\fs24 \cf1\cb2\highlight2 \tab \cf3 public\cf1  \cf3 class\cf1  \cf4 ReportF24\par ??\cf1 \tab \{\par ??\tab \tab \cf4 BaseFont\cf1  \cf5 m_baseFont\cf1 ;\par ??\tab \tab \cf4 PdfContentByte\cf1  \cf5 m_contentByte\cf1 ;\par ??\tab \tab \cf4 Document\cf1  \cf5 m_document\cf1 ;\par ??\tab \tab \cf4 PdfImportedPage\cf1  \cf5 m_templatePage\cf1 ;\par ??\par ??\tab \tab \cf3 public\cf1  \cf5 ReportF24\cf1 ()\par ??\tab \tab \{\par ??\tab \tab \}\par ??\par ??\tab \tab \cf3 public\cf1  \cf3 void\cf1  \cf5 Open\cf1 (\cf3 string\cf1  \cf5 templateFileName\cf1 , \cf3 string\cf1  \cf5 fileName\cf1 )\par ??\tab \tab \{\par ??\tab \tab \tab \cf4 PdfReader\cf1  \cf5 reader\cf1  = \cf3 new\cf1  \cf4 PdfReader\cf1 (\cf5 templateFileName\cf1 );\par ??\tab \tab \tab \cf4 Rectangle\cf1  \cf5 pageSize\cf1  = \cf5 reader\cf1 .\cf5 GetPageSize\cf1 (1);\par ??\tab \tab \tab \cf5 m_document\cf1  = \cf3 new\cf1  \cf4 Document\cf1 (\cf5 pageSize\cf1 , 50, 50, 50, 50);\par ??\tab \tab \tab \cf4 PdfWriter\cf1  \cf5 writer\cf1  = \cf4 PdfWriter\cf1 .\cf5 GetInstance\cf1 (\cf5 m_document\cf1 , \cf3 new\cf1  \cf4 FileStream\cf1 (\cf5 fileName\cf1 , \cf4 FileMode\cf1 .\cf5 Create\cf1 ));\par ??\tab \tab \tab \cf5 m_document\cf1 .\cf5 Open\cf1 ();\par ??\tab \tab \tab \cf5 m_contentByte\cf1  = \cf5 writer\cf1 .\cf5 DirectContent\cf1 ;\par ??\tab \tab \tab \cf5 m_templatePage\cf1  = \cf5 writer\cf1 .\cf5 GetImportedPage\cf1 (\cf5 reader\cf1 , 1);\par ??\tab \tab \tab \cf5 m_baseFont\cf1  = \cf4 BaseFont\cf1 .\cf5 CreateFont\cf1 (\cf4 BaseFont\cf1 .\cf5 HELVETICA\cf1 , \cf4 BaseFont\cf1 .\cf5 CP1252\cf1 , \cf4 BaseFont\cf1 .\cf5 NOT_EMBEDDED\cf1 );\par ??\tab \tab \}\par ??\par ??\tab \tab \cf3 public\cf1  \cf3 void\cf1  \cf5 AddF24\cf1 (\cf4 ModuloF24\cf1  \cf5 f24\cf1 )\par ??\tab \tab \{\par ??\tab \tab \tab \cf5 m_document\cf1 .\cf5 NewPage\cf1 ();\par ??\tab \tab \tab \cf5 m_contentByte\cf1 .\cf5 AddTemplate\cf1 (\cf5 m_templatePage\cf1 , 0, 0);\par ??\par ??\tab \tab \tab \cf5 m_contentByte\cf1 .\cf5 BeginText\cf1 ();\par ??\tab \tab \tab \cf5 m_contentByte\cf1 .\cf5 SetFontAndSize\cf1 (\cf5 m_baseFont\cf1 , 12);\par ??\par ??\tab \tab \tab \cf5 m_contentByte\cf1 .\cf5 ShowTextAligned\cf1 (\cf4 PdfContentByte\cf1 .\cf5 ALIGN_LEFT\cf1 , \cf5 f24\cf1 .\cf5 CodiceFiscale\cf1 , 125, 720, 0);\par ??\tab \tab \tab \cf5 m_contentByte\cf1 .\cf5 ShowTextAligned\cf1 (\cf4 PdfContentByte\cf1 .\cf5 ALIGN_LEFT\cf1 , \cf5 GetDenominazioneCondominio\cf1 (\cf5 f24\cf1 .\cf5 Denominazione\cf1 ), 125, 700, 0);\par ??\tab \tab \tab \cf5 m_contentByte\cf1 .\cf5 ShowTextAligned\cf1 (\cf4 PdfContentByte\cf1 .\cf5 ALIGN_LEFT\cf1 , \cf5 f24\cf1 .\cf5 Comune\cf1 , 125, 650, 0);\par ??\tab \tab \tab \cf5 m_contentByte\cf1 .\cf5 ShowTextAligned\cf1 (\cf4 PdfContentByte\cf1 .\cf5 ALIGN_LEFT\cf1 , \cf5 f24\cf1 .\cf5 Provincia\cf1 , 330, 650, 0);\par ??\tab \tab \tab \cf5 m_contentByte\cf1 .\cf5 ShowTextAligned\cf1 (\cf4 PdfContentByte\cf1 .\cf5 ALIGN_LEFT\cf1 , \cf5 f24\cf1 .\cf5 Indirizzo\cf1 , 370, 650, 0);\par ??\par ??\tab \tab \tab \cf3 float\cf1  \cf5 yRigo\cf1  = 613;\par ??\tab \tab \tab \cf3 foreach\cf1  (\cf4 RigoErario\cf1  \cf5 rigoErario\cf1  \cf3 in\cf1  \cf5 f24\cf1 .\cf5 RighiErario\cf1 )\par ??\tab \tab \tab \{\par ??\tab \tab \tab \tab \cf5 m_contentByte\cf1 .\cf5 ShowTextAligned\cf1 (\cf4 PdfContentByte\cf1 .\cf5 ALIGN_LEFT\cf1 , \cf5 rigoErario\cf1 .\cf5 CodiceTributo\cf1 , 160, \cf5 yRigo\cf1 , 0);\par ??\tab \tab \tab \tab \cf5 m_contentByte\cf1 .\cf5 ShowTextAligned\cf1 (\cf4 PdfContentByte\cf1 .\cf5 ALIGN_LEFT\cf1 , \cf3 string\cf1 .\cf5 Format\cf1 (\cf6 "\{0:0000\}"\cf1 , \cf5 rigoErario\cf1 .\cf5 Mese\cf1 ), 230, \cf5 yRigo\cf1 , 0);\par ??\tab \tab \tab \tab \cf5 m_contentByte\cf1 .\cf5 ShowTextAligned\cf1 (\cf4 PdfContentByte\cf1 .\cf5 ALIGN_LEFT\cf1 , \cf3 string\cf1 .\cf5 Format\cf1 (\cf6 "\{0:0000\}"\cf1 , \cf5 rigoErario\cf1 .\cf5 Anno\cf1 ), 280, \cf5 yRigo\cf1 , 0);\par ??\tab \tab \tab \tab \cf5 m_contentByte\cf1 .\cf5 ShowTextAligned\cf1 (\cf4 PdfContentByte\cf1 .\cf5 ALIGN_RIGHT\cf1 , \cf3 string\cf1 .\cf5 Format\cf1 (\cf6 "\{0:0.00\}"\cf1 , \cf5 rigoErario\cf1 .\cf5 Importo\cf1 ), 400, \cf5 yRigo\cf1 ,\par ??\tab \tab \tab \tab                               0);\par ??\tab \tab \tab \tab \cf5 yRigo\cf1  -= 12;\par ??\tab \tab \tab \}\par ??\par ??\tab \tab \tab \cf5 m_contentByte\cf1 .\cf5 ShowTextAligned\cf1 (\cf4 PdfContentByte\cf1 .\cf5 ALIGN_RIGHT\cf1 , \cf3 string\cf1 .\cf5 Format\cf1 (\cf6 "\{0:0.00\}"\cf1 , \cf5 f24\cf1 .\cf5 Totale\cf1 ), 400, 540, 0);\par ??\tab \tab \tab \cf5 m_contentByte\cf1 .\cf5 ShowTextAligned\cf1 (\cf4 PdfContentByte\cf1 .\cf5 ALIGN_RIGHT\cf1 , \cf3 string\cf1 .\cf5 Format\cf1 (\cf6 "\{0:0.00\}"\cf1 , \cf5 f24\cf1 .\cf5 Totale\cf1 ), 575, 540, 0);\par ??\par ??\tab \tab \tab \cf5 m_contentByte\cf1 .\cf5 ShowTextAligned\cf1 (\cf4 PdfContentByte\cf1 .\cf5 ALIGN_RIGHT\cf1 , \cf3 string\cf1 .\cf5 Format\cf1 (\cf6 "\{0:0.00\}"\cf1 , \cf5 f24\cf1 .\cf5 Totale\cf1 ), 575, 120, 0);\par ??\par ??\tab \tab     \cf3 string\cf1  \cf5 giorno\cf1  = \cf5 f24\cf1 .\cf5 DataPagamento\cf1 .\cf5 Day\cf1 .\cf5 ToString\cf1 (\cf6 "00"\cf1 );\par ??            \cf3 string\cf1  \cf5 mese\cf1  = \cf5 f24\cf1 .\cf5 DataPagamento\cf1 .\cf5 Month\cf1 .\cf5 ToString\cf1 (\cf6 "00"\cf1 );\par ??            \cf3 string\cf1  \cf5 anno\cf1  = \cf5 f24\cf1 .\cf5 DataPagamento\cf1 .\cf5 Year\cf1 .\cf5 ToString\cf1 ();\par ??            \cf5 m_contentByte\cf1 .\cf5 ShowTextAligned\cf1 (\cf4 PdfContentByte\cf1 .\cf5 ALIGN_LEFT\cf1 , \cf5 giorno\cf1 , 30, 50, 0);\par ??            \cf5 m_contentByte\cf1 .\cf5 ShowTextAligned\cf1 (\cf4 PdfContentByte\cf1 .\cf5 ALIGN_LEFT\cf1 , \cf5 mese\cf1 , 60, 50, 0);\par ??            \cf5 m_contentByte\cf1 .\cf5 ShowTextAligned\cf1 (\cf4 PdfContentByte\cf1 .\cf5 ALIGN_LEFT\cf1 , \cf5 anno\cf1 , 90, 50, 0);\par ??\par ??\tab \tab \tab \cf5 m_contentByte\cf1 .\cf5 EndText\cf1 ();\par ??\tab \tab \}\par ??\par ??\tab \tab \cf3 public\cf1  \cf3 void\cf1  \cf5 Close\cf1 ()\par ??\tab \tab \{\par ??\tab \tab \tab \cf5 m_document\cf1 .\cf5 Close\cf1 ();\par ??\tab \tab \}\par ??\par ??        \cf3 private\cf1  \cf3 static\cf1  \cf3 string\cf1  \cf5 GetDenominazioneCondominio\cf1 (\cf3 string\cf1  \cf5 denominazione\cf1 )\par ??        \{\par ??            \cf3 if\cf1  (\cf5 denominazione\cf1 .\cf5 IndexOf\cf1 (\cf6 "condominio"\cf1 , 0, \cf4 StringComparison\cf1 .\cf5 CurrentCultureIgnoreCase\cf1 ) == -1)\par ??            \{\par ??                \cf3 return\cf1  \cf6 "CONDOMINIO "\cf1  + \cf5 denominazione\cf1 ;\par ??            \}\par ??\par ??            \cf3 return\cf1  \cf5 denominazione\cf1 ;\par ??        \}\par ??\tab \}\par ??}
--&gt;
&lt;div style="background: rgb(24, 24, 24) none repeat scroll 0%; font-family: Consolas; font-size: 12pt; color: rgb(224, 224, 224); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;class&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;ReportF24&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(199, 199, 241);"&gt;BaseFont&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;m_baseFont&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(199, 199, 241);"&gt;PdfContentByte&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;m_contentByte&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(199, 199, 241);"&gt;Document&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;m_document&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(199, 199, 241);"&gt;PdfImportedPage&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;m_templatePage&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;Open&lt;/span&gt;(&lt;span style="color: rgb(128, 128, 192);"&gt;string&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;templateFileName&lt;/span&gt;, &lt;span style="color: rgb(128, 128, 192);"&gt;string&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;fileName&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(199, 199, 241);"&gt;PdfReader&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;reader&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;PdfReader&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;templateFileName&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(199, 199, 241);"&gt;Rectangle&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;pageSize&lt;/span&gt; = &lt;span style="color: rgb(254, 241, 169);"&gt;reader&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;GetPageSize&lt;/span&gt;(1);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;m_document&lt;/span&gt; = &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;Document&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;pageSize&lt;/span&gt;, 50, 50, 50, 50);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(199, 199, 241);"&gt;PdfWriter&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt; = &lt;span style="color: rgb(199, 199, 241);"&gt;PdfWriter&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;GetInstance&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;m_document&lt;/span&gt;, &lt;span style="color: rgb(128, 128, 192);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(199, 199, 241);"&gt;FileStream&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;fileName&lt;/span&gt;, &lt;span style="color: rgb(199, 199, 241);"&gt;FileMode&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Create&lt;/span&gt;));&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;m_document&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Open&lt;/span&gt;();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;m_contentByte&lt;/span&gt; = &lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;DirectContent&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;m_templatePage&lt;/span&gt; = &lt;span style="color: rgb(254, 241, 169);"&gt;writer&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;GetImportedPage&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;reader&lt;/span&gt;, 1);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;m_baseFont&lt;/span&gt; = &lt;span style="color: rgb(199, 199, 241);"&gt;BaseFont&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;CreateFont&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;BaseFont&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;HELVETICA&lt;/span&gt;, &lt;span style="color: rgb(199, 199, 241);"&gt;BaseFont&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;CP1252&lt;/span&gt;, &lt;span style="color: rgb(199, 199, 241);"&gt;BaseFont&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;NOT_EMBEDDED&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(128, 128, 192);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;void&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;AddF24&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;ModuloF24&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;f24&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;m_document&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;NewPage&lt;/span&gt;();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;m_contentByte&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;AddTemplate&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;m_templatePage&lt;/span&gt;, 0, 0);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;m_contentByte&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;BeginText&lt;/span&gt;();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;m_contentByte&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;SetFontAndSize&lt;/span&gt;(&lt;span style="color: rgb(254, 241, 169);"&gt;m_baseFont&lt;/span&gt;, 12);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;m_contentByte&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;ShowTextAligned&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;PdfContentByte&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;ALIGN_LEFT&lt;/span&gt;, &lt;span style="color: rgb(254, 241, 169);"&gt;f24&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;CodiceFiscale&lt;/span&gt;, 125, 720, 0);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;m_contentByte&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;ShowTextAligned&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;PdfContentByte&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;ALIGN_LEFT&lt;/span&gt;,      &lt;span style="color: rgb(254, 241, 169);"&gt;f24&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Denominazione&lt;/span&gt;, 125, 700, 0);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;m_contentByte&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;ShowTextAligned&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;PdfContentByte&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;ALIGN_LEFT&lt;/span&gt;, &lt;span style="color: rgb(254, 241, 169);"&gt;f24&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Comune&lt;/span&gt;, 125, 650, 0);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;m_contentByte&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;ShowTextAligned&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;PdfContentByte&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;ALIGN_LEFT&lt;/span&gt;, &lt;span style="color: rgb(254, 241, 169);"&gt;f24&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Provincia&lt;/span&gt;, 330, 650, 0);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(254, 241, 169);"&gt;m_contentByte&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;ShowTextAligned&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;PdfContentByte&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;ALIGN_LEFT&lt;/span&gt;, &lt;span style="color: rgb(254, 241, 169);"&gt;f24&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Indirizzo&lt;/span&gt;, 370, 650, 0);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(128, 128, 192);"&gt;float&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;yRigo&lt;/span&gt; = 613;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            &lt;span style="color: rgb(128, 128, 192);"&gt;foreach&lt;/span&gt; (&lt;span style="color: rgb(199, 199, 241);"&gt;RigoErario&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;rigoErario&lt;/span&gt; &lt;span style="color: rgb(128, 128, 192);"&gt;in&lt;/span&gt; &lt;span style="color: rgb(254, 241, 169);"&gt;f24&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;RighiErario&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                &lt;span style="color: rgb(254, 241, 169);"&gt;m_contentByte&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;ShowTextAligned&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;PdfContentByte&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;ALIGN_LEFT&lt;/span&gt;, &lt;/p&gt;
&lt;p style="margin: 0px 0px 0px 200px;"&gt;&lt;span style="color: rgb(254, 241, 169);"&gt;rigoErario&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;CodiceTributo&lt;/span&gt;, 160, &lt;span style="color: rgb(254, 241, 169);"&gt;yRigo&lt;/span&gt;, 0);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                &lt;span style="color: rgb(254, 241, 169);"&gt;m_contentByte&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;ShowTextAligned&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;PdfContentByte&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;ALIGN_LEFT&lt;/span&gt;, &lt;/p&gt;
&lt;p style="margin: 0px 0px 0px 200px;"&gt;&lt;span style="color: rgb(128, 128, 192);"&gt;string&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Format&lt;/span&gt;(&lt;span style="color: rgb(96, 255, 96);"&gt;"{0:0000}"&lt;/span&gt;, &lt;span style="color: rgb(254, 241, 169);"&gt;rigoErario&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Mese&lt;/span&gt;), 230, &lt;span style="color: rgb(254, 241, 169);"&gt;yRigo&lt;/span&gt;, 0);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                &lt;span style="color: rgb(254, 241, 169);"&gt;m_contentByte&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;ShowTextAligned&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;PdfContentByte&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;ALIGN_LEFT&lt;/span&gt;, &lt;/p&gt;
&lt;p style="margin: 0px 0px 0px 200px;"&gt;&lt;span style="color: rgb(128, 128, 192);"&gt;string&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Format&lt;/span&gt;(&lt;span style="color: rgb(96, 255, 96);"&gt;"{0:0000}"&lt;/span&gt;, &lt;span style="color: rgb(254, 241, 169);"&gt;rigoErario&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Anno&lt;/span&gt;), 280, &lt;span style="color: rgb(254, 241, 169);"&gt;yRigo&lt;/span&gt;, 0);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;                &lt;span style="color: rgb(254, 241, 169);"&gt;m_contentByte&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;ShowTextAligned&lt;/span&gt;(&lt;span style="color: rgb(199, 199, 241);"&gt;PdfContentByte&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;ALIGN_RIGHT&lt;/span&gt;, &lt;/p&gt;
&lt;p style="margin: 0px 0px 0px 200px;"&gt;&lt;span style="color: rgb(128, 128, 192);"&gt;string&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Format&lt;/span&gt;(&lt;span style="color: rgb(96, 255, 96);"&gt;"{0:0.00}"&lt;/span&gt;, &lt;span style="color: rgb(254, 241, 169);"&gt;rigoErario&lt;/span&gt;.&lt;span style="color: rgb(254, 241, 169);"&gt;Importo&lt;/span&gt;