<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.devleap.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Paolo Pialorsi : WF</title><link>http://blogs.devleap.com/paolo/archive/tags/WF/default.aspx</link><description>Tags: WF</description><dc:language>en</dc:language><generator>CommunityServer 2007 SP2 (Build: 20611.960)</generator><item><title>WF Security Pack CTP 1</title><link>http://blogs.devleap.com/paolo/archive/2010/07/14/wf-security-pack-ctp-1.aspx</link><pubDate>Wed, 14 Jul 2010 00:51:27 GMT</pubDate><guid isPermaLink="false">723bc1d7-e66b-4192-854d-44fd94d7f9a3:22295</guid><dc:creator>paolo</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.devleap.com/paolo/rsscomments.aspx?PostID=22295</wfw:commentRss><comments>http://blogs.devleap.com/paolo/archive/2010/07/14/wf-security-pack-ctp-1.aspx#comments</comments><description>&lt;p&gt;Pochi giorni fa è stato rilasciato su &lt;a href="http://wf.codeplex.com/"&gt;CodePlex&lt;/a&gt; un aggiornamento delle estensioni di WF prodotte direttamente dal team di prodotto.&lt;/p&gt;  &lt;p&gt;In particolare ci tengo a segnalare il &lt;a href="http://wf.codeplex.com/releases/view/48114"&gt;WF Security Pack&lt;/a&gt; attualmente in CTP 1 perché mi sembra molto interessante l’idea di avere delle activity dentro WF 4 che consentano di integrarsi con WIF, con la Claim based authentication e con scenari complessi di ActAs via WS-Trust.&lt;/p&gt;&lt;img src="http://blogs.devleap.com/aggbug.aspx?PostID=22295" width="1" height="1"&gt;</description><category domain="http://blogs.devleap.com/paolo/archive/tags/WCF/default.aspx">WCF</category><category domain="http://blogs.devleap.com/paolo/archive/tags/WF/default.aspx">WF</category><category domain="http://blogs.devleap.com/paolo/archive/tags/WIF/default.aspx">WIF</category></item><item><title>Migrare da WF3 a WF4</title><link>http://blogs.devleap.com/paolo/archive/2010/04/06/migrare-da-wf3-a-wf4.aspx</link><pubDate>Tue, 06 Apr 2010 11:30:00 GMT</pubDate><guid isPermaLink="false">723bc1d7-e66b-4192-854d-44fd94d7f9a3:19431</guid><dc:creator>paolo</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.devleap.com/paolo/rsscomments.aspx?PostID=19431</wfw:commentRss><comments>http://blogs.devleap.com/paolo/archive/2010/04/06/migrare-da-wf3-a-wf4.aspx#comments</comments><description>&lt;p&gt;Come abbiamo iniziato ad evidenziare ormai quasi 2 anni fa ad una delle nostre &lt;a href="http://devcon.devleap.com/"&gt;DevCon&lt;/a&gt; la ormai imminente (è questione di giorni) versione di WF presente in .NET 4.0 sarà molto (possiamo dire “radicalmente”?) diversa da WF3.&lt;/p&gt;  &lt;p&gt;Il problema non è solo imparare ad usare un nuovo motore di workflow, ma soprattutto decidere se e come migrare le soluzioni esistenti e basate su WF3 verso il nuovo WF4.&lt;/p&gt;  &lt;p&gt;In questo &lt;a href="http://wf.codeplex.com/"&gt;nuovo progetto&lt;/a&gt; su CodePlex, gestito direttamente dal team di WF di Microsoft, ci sono alcune risposte. Sicuramente è degno di nota il fatto che, essendo su CodePlex, ci sono anche i sorgenti del progetto, molto utili per uno studio individuale e una personalizzazione su progetti specifici del modello di upgrade del codice da WF3 a WF4.&lt;/p&gt;&lt;img src="http://blogs.devleap.com/aggbug.aspx?PostID=19431" width="1" height="1"&gt;</description><category domain="http://blogs.devleap.com/paolo/archive/tags/WF/default.aspx">WF</category><category domain="http://blogs.devleap.com/paolo/archive/tags/.NET+4.0/default.aspx">.NET 4.0</category></item><item><title>Microsoft SharePoint 2010: prodotto svelato e nuovo corso DevLeap</title><link>http://blogs.devleap.com/paolo/archive/2009/10/20/microsoft-sharepoint-2010-prodotto-svelato-e-nuovo-corso-devleap.aspx</link><pubDate>Tue, 20 Oct 2009 00:56:39 GMT</pubDate><guid isPermaLink="false">723bc1d7-e66b-4192-854d-44fd94d7f9a3:19229</guid><dc:creator>paolo</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.devleap.com/paolo/rsscomments.aspx?PostID=19229</wfw:commentRss><comments>http://blogs.devleap.com/paolo/archive/2009/10/20/microsoft-sharepoint-2010-prodotto-svelato-e-nuovo-corso-devleap.aspx#comments</comments><description>&lt;p&gt;Oggi, durante la keynote della &lt;a href="http://www.mssharepointconference.com/"&gt;Microsoft SharePoint Conference 2009&lt;/a&gt; in Las Vegas, è stato pubblicamente svelato Microsoft SharePoint Server 2010.&lt;/p&gt;  &lt;p&gt;Ci sono da oggi diversi siti e aree online dedicati all’argomento, come &lt;a href="http://blogs.msdn.com/sharepoint/archive/2009/10/19/sharepoint-2010-resources.aspx"&gt;segnalato&lt;/a&gt; dal team di prodotto nel suo &lt;a href="http://blogs.msdn.com/sharepoint"&gt;blog ufficiale&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Per quanto riguarda noi di DevLeap, oltre a dare appuntamento alla &lt;a href="http://www.sharepointfuture.com/"&gt;SharePoint Future&lt;/a&gt; della prossima settimana (per chi ce l’ha fatta ad iscriversi prima del sold out), segnalo che da oggi (nel rispetto delle NDA non potevamo pubblicarlo prima) è stato ufficializzato un nuovo corso dal titolo &lt;a href="http://www.devleap.com/document.aspx?id=3889"&gt;“Microsoft SharePoint 2010 Development”&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.devleap.com/aggbug.aspx?PostID=19229" width="1" height="1"&gt;</description><category domain="http://blogs.devleap.com/paolo/archive/tags/SharePoint/default.aspx">SharePoint</category><category domain="http://blogs.devleap.com/paolo/archive/tags/WF/default.aspx">WF</category><category domain="http://blogs.devleap.com/paolo/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://blogs.devleap.com/paolo/archive/tags/.NET+4.0/default.aspx">.NET 4.0</category></item><item><title>Workflow 4.0</title><link>http://blogs.devleap.com/paolo/archive/2009/06/11/workflow-4-0.aspx</link><pubDate>Thu, 11 Jun 2009 08:03:20 GMT</pubDate><guid isPermaLink="false">723bc1d7-e66b-4192-854d-44fd94d7f9a3:19101</guid><dc:creator>paolo</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.devleap.com/paolo/rsscomments.aspx?PostID=19101</wfw:commentRss><comments>http://blogs.devleap.com/paolo/archive/2009/06/11/workflow-4-0.aspx#comments</comments><description>&lt;p&gt;Come molti di voi avranno notato, nella CTP di VS2010 uscita il mese scorso manca il template di workflow di tipo State Machine. Con .NET 4.0 il motore di WF4 è stato praticamente riscritto, il prodotto è stato completamente integrato con &lt;a href="http://blogs.msdn.com/endpoint/archive/2009/05/07/the-road-to-4-wcf-changes-between-beta-1-and-ctp.aspx"&gt;WCF4&lt;/a&gt; (i due team di prodotto infatti si sono fusi, forse dovremmo parlare di “fusione per incorporazione” di WF :-) …). Ora in WF4 i workflow saranno orientati solo al markup e non dovrebbe più esistere il concetto di code beside di un workflow. Anche il set di activity di base (vedi &lt;a href="http://blogs.msdn.com/endpoint/archive/2009/05/29/a-tour-on-the-wf4-activity-palette.aspx"&gt;qui&lt;/a&gt; per averne un’idea) e il modello di estendibilità delle activity personalizzate sono cambiati. Ora le activity non sono più classi derivate dalla classe base Activity, ma classi di una delle seguenti tipologie:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;WorkflowElement: classe base astratta per tutte le tipologie di activity&lt;/li&gt; &lt;li&gt;Activity: definite come markup e frutto della composizione di altre activity, come i workflow stessi&lt;/li&gt; &lt;li&gt;CodeActivity: classe base per le activity definite come codice, con l’override del metodo di Execute&lt;/li&gt; &lt;li&gt;NativeActivity: classe base per le activity definite come codice, che devono interfacciarsi con il motore di base di WF4, con il sistema di messaggi a code (ora ribattezzate bookmark), ecc.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;In questo contesto sono stati inseriti dei nuovi modelli di workflow. Nello specifico esiste ancora, seppur ridefinito con nuove activity e con un nuovo designer, il modello di Sequential workflow. Esiste un nuovo modello di workflow chiamato Flowchart, che può anche essere una parte di un workflow Sequential. Come citavo all’inizio del post poi non esiste più il modello di tipo State Machine. Mentre inizialmente (lo scorso anno) si ipotizzava che la causa di questa assenza fosse un porting non ancora completato del motore, ora è chiaro che lo State Machine non sarà supportato, almeno inizialmente. Infatti come spiegato in &lt;a href="http://blogs.msdn.com/endpoint/archive/2009/06/05/migration-guidance-for-the-wf-developer.aspx"&gt;questa serie di documenti&lt;/a&gt; sulla migrazione da WF3 a WF4 con un modello di tipo Flowchart è possibile riprodurre il comportamento di uno State Machine.&lt;/p&gt; &lt;p&gt;Ovviamente, per quella che è la natura di .NET Framework, in .NET 4.0 sarà possibile avere comunque il supporto ai workflow definiti con il motore di .NET 3.0 e di WF3, come è spiegato anche &lt;a href="http://blogs.msdn.com/endpoint/archive/2009/06/01/workflow-4-0-templates.aspx"&gt;qui&lt;/a&gt;, quindi non dobbiamo necessariamente buttare tutto il lavoro già svolto in WF3, soprattutto se abbiamo lavorato con le State Machine. Tuttavia è consigliabile iniziare a pensare ad un percorso di migrazione.&lt;/p&gt;&lt;img src="http://blogs.devleap.com/aggbug.aspx?PostID=19101" width="1" height="1"&gt;</description><category domain="http://blogs.devleap.com/paolo/archive/tags/WCF/default.aspx">WCF</category><category domain="http://blogs.devleap.com/paolo/archive/tags/WF/default.aspx">WF</category><category domain="http://blogs.devleap.com/paolo/archive/tags/.NET+4.0/default.aspx">.NET 4.0</category></item><item><title>SharePoint Workflow: due articoli utili</title><link>http://blogs.devleap.com/paolo/archive/2008/06/13/sharepoint-workflow-due-articoli-utili.aspx</link><pubDate>Fri, 13 Jun 2008 12:24:15 GMT</pubDate><guid isPermaLink="false">723bc1d7-e66b-4192-854d-44fd94d7f9a3:18497</guid><dc:creator>paolo</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.devleap.com/paolo/rsscomments.aspx?PostID=18497</wfw:commentRss><comments>http://blogs.devleap.com/paolo/archive/2008/06/13/sharepoint-workflow-due-articoli-utili.aspx#comments</comments><description>&lt;p&gt;Per chi vuole &amp;quot;avviarsi&amp;quot; allo sviluppo di Workflow per SharePoint, segnalo due articoli utili scritti da David Man e pubblicati su MSDN:&lt;/p&gt; &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/cc546557.aspx"&gt;http://msdn.microsoft.com/en-us/library/cc546557.aspx&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/cc546558.aspx"&gt;http://msdn.microsoft.com/en-us/library/cc546558.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.devleap.com/aggbug.aspx?PostID=18497" width="1" height="1"&gt;</description><category domain="http://blogs.devleap.com/paolo/archive/tags/SharePoint/default.aspx">SharePoint</category><category domain="http://blogs.devleap.com/paolo/archive/tags/WF/default.aspx">WF</category></item><item><title>SharePoint Designer, Code Access Security e Folder Redirection</title><link>http://blogs.devleap.com/paolo/archive/2008/01/10/sharepoint-designer-code-access-security-e-folder-redirection.aspx</link><pubDate>Thu, 10 Jan 2008 15:36:20 GMT</pubDate><guid isPermaLink="false">723bc1d7-e66b-4192-854d-44fd94d7f9a3:18260</guid><dc:creator>paolo</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.devleap.com/paolo/rsscomments.aspx?PostID=18260</wfw:commentRss><comments>http://blogs.devleap.com/paolo/archive/2008/01/10/sharepoint-designer-code-access-security-e-folder-redirection.aspx#comments</comments><description>&lt;p&gt;Un titolo complicato :-) per un post semplice!&lt;/p&gt; &lt;p&gt;Oggi ho riscontrato un problema con SharePoint Designer 2007. Da un PC del dominio del mio ufficio, con i profili e i folder salvati su Distributed File System via Group Policy, non riuscivo a creare workflow su un site MOSS2007.&lt;br /&gt;Il problema era in realtà molto semplice: il folder che contiene gli Application Data degli utenti, viene utilizzato da SD2007 per salvare in una cache temporane degli assembly, tra cui quelli con le activity offerte dai vari portali MOSS2007/WSS3 a cui ci si collega.&lt;/p&gt; &lt;p&gt;In pratica in&amp;nbsp; &amp;lt;User Folder&amp;gt;\Application Data\Microsoft\SharePoint Designer\ProxyAssemblyCache\12.x.y.z vengono salvati gli assembly scaricati dai vari server MOSS2007/WSS3. SD2007 poi carica questi assembly per metterceli a disposizione durante la definizione dei workflow. Ora dal momento che nel mio caso il folder &amp;lt;User Folder&amp;gt;\Application Data\ risiedeva su di una share raggiunta via DFS, la Code Access Security di .NET - giustamente - non dava un livello di trust adeguato agli assembly, quindi SD2007 falliva durante il loro caricamento.&lt;/p&gt; &lt;p&gt;L&amp;#39;errore restituito era un criptico po&amp;#39;: &amp;quot;Failed to load the workflow&amp;quot;. Guardando però cosa SD2007 tentava di caricare, ho capito l&amp;#39;arcano mistero. Sono dovuto andare in &amp;quot;Microsoft .NET Framework 2.0 Configuration&amp;quot; dagli strumenti amministrativi della macchina, per definire un code group (a livello di macchina nel mio caso) che corrispondesse alla URL &lt;a&gt;\\dominio\DFSRoot\&lt;/a&gt;* (attenzione al \* in fondo che è necessario) per dire poi che volevo dare ai file provenienti da quella URL un livello di trust pari a quello che ho su &amp;quot;My Computer&amp;quot;, simulando il fatto che i file provengano dal mio disco locale anziché dal profilo sul server, cioè in questo caso &amp;quot;Full Trust&amp;quot;. Ora tutto funziona regolarmente.&lt;/p&gt; &lt;p&gt;Probabilmente se non avessi saputo come funziona la Code Access Security di .NET ... sarei ancora lì :-) a cercare la causa del problema. Per questo insisto sempre sul fatto che anche i sistemisti dovrebbero conoscere almeno di massima il funzionamento di .NET!&lt;/p&gt;&lt;img src="http://blogs.devleap.com/aggbug.aspx?PostID=18260" width="1" height="1"&gt;</description><category domain="http://blogs.devleap.com/paolo/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blogs.devleap.com/paolo/archive/tags/SharePoint/default.aspx">SharePoint</category><category domain="http://blogs.devleap.com/paolo/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.devleap.com/paolo/archive/tags/WF/default.aspx">WF</category></item><item><title>Acropolis sarà incluso in versioni future di .NET Framework</title><link>http://blogs.devleap.com/paolo/archive/2007/10/30/acropolis-sar-224-incluso-in-versioni-future-di-net-framework.aspx</link><pubDate>Tue, 30 Oct 2007 13:20:18 GMT</pubDate><guid isPermaLink="false">723bc1d7-e66b-4192-854d-44fd94d7f9a3:18054</guid><dc:creator>paolo</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.devleap.com/paolo/rsscomments.aspx?PostID=18054</wfw:commentRss><comments>http://blogs.devleap.com/paolo/archive/2007/10/30/acropolis-sar-224-incluso-in-versioni-future-di-net-framework.aspx#comments</comments><description>&lt;p&gt;Di Acropolis &lt;a href="http://weblogs.asp.net/paolopia/archive/2007/06/08/acropolis-cab-wpf-pageflow-what-should-i-suggest-to-use.aspx"&gt;ne avevamo già parlato&lt;/a&gt; durante TechEd 2007. Dopo alcuni mesi di silenzio, successivi alla presentazione a TechEd 2007, il &lt;a href="http://blogs.msdn.com/acropolis/archive/2007/10/29/An-Acropolis-Update.aspx"&gt;team del prodotto&lt;/a&gt; ha annunciato che Acropolis farà parte di una delle versioni future di .NET Framework. Nel frattempo però non avremo nuove CTP ma solo un documento di Patterns &amp;amp; Practices, prima o poi disponibile, intanto teniamo d&amp;#39;occhio&amp;nbsp;&lt;a href="http://blogs.msdn.com/gblock/archive/2007/10/26/wpf-composite-client-guidance-it-s-coming.aspx"&gt;qui&lt;/a&gt;.&amp;nbsp;Questa è una notizia importante per tutti coloro i quali devono scegliere se e come implementare la gestione della UI nelle loro applicazioni. Infatti se ad oggi si sviluppa su Windows Forms, si&amp;nbsp;può decidere di valutare CAB (ma anche no :-) ...) mentre nell&amp;#39;ambito di WPF potrebbe essere Acropolis la linea guida da seguire. Mi auguro che resti valida anche l&amp;#39;idea, mostrata in fase di presentazione del progetto, di rendere utilizzabili dei workflow di WF per il controllo della UI. Staremo a vedere ...&lt;/p&gt;&lt;img src="http://blogs.devleap.com/aggbug.aspx?PostID=18054" width="1" height="1"&gt;</description><category domain="http://blogs.devleap.com/paolo/archive/tags/Windows+Vista/default.aspx">Windows Vista</category><category domain="http://blogs.devleap.com/paolo/archive/tags/Smart+Client/default.aspx">Smart Client</category><category domain="http://blogs.devleap.com/paolo/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blogs.devleap.com/paolo/archive/tags/WF/default.aspx">WF</category></item><item><title>Rules di WF senza Workflow</title><link>http://blogs.devleap.com/paolo/archive/2007/05/27/rules-di-wf-senza-workflow.aspx</link><pubDate>Sun, 27 May 2007 19:07:45 GMT</pubDate><guid isPermaLink="false">723bc1d7-e66b-4192-854d-44fd94d7f9a3:17392</guid><dc:creator>paolo</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.devleap.com/paolo/rsscomments.aspx?PostID=17392</wfw:commentRss><comments>http://blogs.devleap.com/paolo/archive/2007/05/27/rules-di-wf-senza-workflow.aspx#comments</comments><description>&lt;p&gt;Questa settimana, durante un corso su WF, ho mostrato come sia possibile utilizzare le rule di WF anche senza avere necessariamente un workflow alle spalle. L'infrastruttura di WF infatti consente di valutare RuleSet anche senza che ci sia un workflow collegato. Dal momento poi che le rule di un workflow sono persistite all'interno di un file .rules (pur sempre XOML) differente da quello che rappresenta il flusso ... facendo 1 + 1 possiamo definire regole esterne da usare in qualsisi programma che abbia bisogno di un motore di regole e poi valutarle con gli oggetti del framework di WF.&lt;/p&gt; &lt;p&gt;Ecco un esempio di codice che carica un file .rules da disco, lo deserializza usando il WorkflowMarkupSerializer, e ne valuta il risultato tramite la classe RuleEngine:&amp;nbsp;&lt;/p&gt; &lt;p class="code" style="font-size:10pt;font-family:courier new;"&gt;XmlTextReader reader = new XmlTextReader(@"..\..\DiscountCouponWorkflow.rules");&lt;br&gt;WorkflowMarkupSerializer serializer = new WorkflowMarkupSerializer();&lt;br&gt;RuleDefinitions rules = serializer.Deserialize(reader) as RuleDefinitions;&lt;br&gt;RuleSet ruleSet = rules.RuleSets["PriceRuleSet"];&lt;br&gt;RuleEngine ruleEngine = new RuleEngine(ruleSet, typeof(Customer));&lt;br&gt;ruleEngine.Execute(c);&lt;/p&gt; &lt;p&gt;Si noti il fatto che passo al motore di rule (l'istanza di RuleEngine) anche un oggetto come input del metodo&amp;nbsp;Execute. Si tratta di un oggetto il cui tipo .NET è stato dichiarato nel costruttore della classe RuleEngine e rappresenta l'input su cui verranno applicate le&amp;nbsp;regole. Ora, utilizzando un'interfaccia che descriva un comportamento comune a N diverse tipologie di oggetti, potremmo avere uno stesso file di regole applicabile sia ad un workflow, che implementa l'interfaccia nella definizione della sua classe, sia ad un nostro oggetto custom.&lt;/p&gt;&lt;img src="http://blogs.devleap.com/aggbug.aspx?PostID=17392" width="1" height="1"&gt;</description><category domain="http://blogs.devleap.com/paolo/archive/tags/.NET+3.0/default.aspx">.NET 3.0</category><category domain="http://blogs.devleap.com/paolo/archive/tags/WF/default.aspx">WF</category></item><item><title>Xceed Activities for WF</title><link>http://blogs.devleap.com/paolo/archive/2007/04/26/xceed-activities-for-wf.aspx</link><pubDate>Thu, 26 Apr 2007 21:45:00 GMT</pubDate><guid isPermaLink="false">723bc1d7-e66b-4192-854d-44fd94d7f9a3:17215</guid><dc:creator>paolo</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.devleap.com/paolo/rsscomments.aspx?PostID=17215</wfw:commentRss><comments>http://blogs.devleap.com/paolo/archive/2007/04/26/xceed-activities-for-wf.aspx#comments</comments><description>&lt;P&gt;Segnalo il rilascio di una serie di Activity "interessanti" per WF, utili per avere il supporto per ZIP, TAR, FTP e Secure-FTP. Trovo che Xceed sia un ottimo produttore di componenti e add-on, quindi segnalo volentieri questo loro &lt;A href="http://xceed.com/Activities_WF_Intro.html"&gt;nuovo prodotto&lt;/A&gt;&amp;nbsp;in cui mi sono imbattuto oggi.&lt;/P&gt;&lt;img src="http://blogs.devleap.com/aggbug.aspx?PostID=17215" width="1" height="1"&gt;</description><category domain="http://blogs.devleap.com/paolo/archive/tags/.NET+3.0/default.aspx">.NET 3.0</category><category domain="http://blogs.devleap.com/paolo/archive/tags/WF/default.aspx">WF</category><category domain="http://blogs.devleap.com/paolo/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category></item><item><title>Orcas March CTP: non solo LINQ, AJAX e WPF, ma anche WorkflowServices</title><link>http://blogs.devleap.com/paolo/archive/2007/03/03/orcas-march-ctp-non-solo-linq-ajax-e-wpf-ma-anche-workflowservices.aspx</link><pubDate>Sat, 03 Mar 2007 16:32:56 GMT</pubDate><guid isPermaLink="false">723bc1d7-e66b-4192-854d-44fd94d7f9a3:16837</guid><dc:creator>paolo</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.devleap.com/paolo/rsscomments.aspx?PostID=16837</wfw:commentRss><comments>http://blogs.devleap.com/paolo/archive/2007/03/03/orcas-march-ctp-non-solo-linq-ajax-e-wpf-ma-anche-workflowservices.aspx#comments</comments><description>&lt;p&gt;Da pochi giorni è &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=B533619A-0008-4DD6-9ED1-47D482683C78&amp;amp;displaylang=en"&gt;disponibile la March CTP&lt;/a&gt; di Visual Studio codename Orcas. Si parla molto e per lo più di LINQ, AJAX e miglior supporto a WPF. Personalmente credo molto in LINQ e mi appassiona vedere come è stato realizzato. AJAX non mi "scalda" :-) più di tanto e WPF ... lo sapete sono solo palle che rimbalzano! (ovviamente scherzo ... ma non sono un uomo che si occupa di UI con WPF, per questo ci sono Luka e RoB nel nostro gruppo). In ogni caso, come segnalato anche in &lt;a href="http://blogs.msdn.com/trobbins/archive/2007/02/28/microsoft-pre-release-software-visual-studio-code-name-orcas-march-2007-community-technology-preview-ctp.aspx"&gt;questo post&lt;/a&gt;, le nuove funzionalità introdotto nella Orcas CTP di Marzo riguardano diversi e numerosi altri ambiti. &lt;/p&gt; &lt;p&gt;Ad esempio ci sono alcune classi e assembly che consentono di ospitare workflow definiti con WF in ServiceHost di WCF. Esiste infatti un assembly di nome System.WorkflowServices che espone una classe di nome System.ServiceModel.Activation.WorkflowServiceHostFactory, che non fa altro che creare una istanza di una classe System.ServiceModel.WorkflowServiceHost, che a sua volta rende accessibile un workflow di WF tramite chiamate SOAP via WCF.&lt;/p&gt; &lt;p&gt;A tale scopo è stata anche definita una coppia di nuovi binding NetTcpContextBinding e WSHttpContextBinding per meglio gestire l'associazione (context) tra le istanze dei flussi e l'infrastruttura di comunicazione. Proprio per questo, sfruttando le caratteristiche dell'architettura estendibile e personalizzabile di WF, è stato definito un nuovo runtime scheduler (System.Workflow.Runtime.Hosting.SynchronizationContextWorkflowSchedulerService) che internamente utilizza il SynchronizationContext di System.Threading e il System.Threading.ThreadPool).&lt;/p&gt; &lt;p&gt;Le potenzialità di questo nuovo "mattoncino" sono evidenti: avere logica di business implementata tramite WF ed esposta in modo rapido tramite WCF, senza richiedere a noi poveri sviluppatori di scrivere "quintali" di codice per gestire le istanze dei workflow, la loro persistenza, il loro stato, ecc.&lt;/p&gt; &lt;p&gt;Se avessi avuto queste opportunità nel progetto che usa WF per la gestione della produzione in stabilimento che ho concluso insieme a &lt;a href="http://blogs.devleap.com/rob/"&gt;RoB&lt;/a&gt; il mese scorso e che sta andando on-line in questi giorni ... beh avrei scritto cordi almeno 15gg di meno ...&lt;/p&gt; &lt;p&gt;Avremo modo di tornare più approfonditamente su questi temi sia in post futuri che magari a &lt;a href="http://devcon.devleap.com/"&gt;DevCon&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.devleap.com/aggbug.aspx?PostID=16837" width="1" height="1"&gt;</description><category domain="http://blogs.devleap.com/paolo/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blogs.devleap.com/paolo/archive/tags/.NET+3.0/default.aspx">.NET 3.0</category><category domain="http://blogs.devleap.com/paolo/archive/tags/WF/default.aspx">WF</category><category domain="http://blogs.devleap.com/paolo/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category></item><item><title>Rientranza delle chiamate in WF</title><link>http://blogs.devleap.com/paolo/archive/2007/02/06/rientranza-delle-chiamate-in-wf.aspx</link><pubDate>Tue, 06 Feb 2007 23:23:27 GMT</pubDate><guid isPermaLink="false">723bc1d7-e66b-4192-854d-44fd94d7f9a3:16629</guid><dc:creator>paolo</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.devleap.com/paolo/rsscomments.aspx?PostID=16629</wfw:commentRss><comments>http://blogs.devleap.com/paolo/archive/2007/02/06/rientranza-delle-chiamate-in-wf.aspx#comments</comments><description>&lt;p&gt;In questi giorni, a seguito di una consulenza su WF, ho potutoverificare in dettaglio alcuni aspetti relativi alla gestione dei thread e delle code in WF.&amp;nbsp;Il motore del WF Runtime utilizza, per default, uno scheduler (DefaultWorkflowSchedulerService) che fornisce al runtime, come impostazione predefinita,&amp;nbsp;un pool di 5 thread, nel caso di macchine mono-processore, oppure un pool di 4 thread per ciascun processore, nel caso di macchine multi-processore. Si tratta di impostazioni modificabili, ma questi numeri hanno un senso, soprattutto rispetto alla scalabilità delle applicazioni server-side, quindi non alzateli "a manetta" perché potrebbe dare effetti peggiori. Ricordate sempre che i thread non sono infiniti e se c'è in mezzo ASP.NET, già lui utilizza il ThreadPool di .NET.&lt;/p&gt; &lt;p&gt;Ciascuna istanza di workflow è eseguita da uno e uno solo di questi thread. Significa che non c'è la possibilità, se non cambiando lo scheduler di default, di eseguire passi di un singolo workflow in parallelo. Se vi state chiedendo come sia possibile allora avere una activity di tipo ParallelActivity o di tipo ListenActivity in un workflow ... &lt;a href="http://blogs.msdn.com/advancedworkflow/archive/2006/02/23/538160.aspx"&gt;ecco una brillante ed esaustiva risposta&lt;/a&gt; da parte del team di WF. In generale vi consiglio di leggere e monitorare l'intero &lt;a href="http://blogs.msdn.com/advancedworkflow/"&gt;blog&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Ora provate ad immaginare un workflow che utilizza una CallExternalMethodActivity per chiamare l'host e il codice dell'host, relativo alla CallExternalMethodActivity,&amp;nbsp;che a sua volta utilizza un evento per richiamare il workflow, che ha una HandleExternalEventActivity definita.&lt;/p&gt; &lt;p&gt;Pensiamo al caso sequenziale:&lt;/p&gt; &lt;p&gt;&lt;img src="http://devlab.devleap.it/PaoloPi/Images/Sequential-FW-01.png"&gt; &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Vi ricordo che il thread che esegue il workflow invoca l'host senza preoccuparsi della thread safety, quindi può chiamare ad esempio un'applicazione Windows Forms che faccia da host, senza utilizzare il thread di UI. Per questa ragione dobbiamo sempre preoccuparci di verificare se siamo o meno sul thread di UI prima di utilizzare eventuali informazioni ottenute dal workflow.&lt;/p&gt; &lt;p&gt;Pensate quindi che si crei un deadlock? Il workflow chiama l'host, l'host chiama il workflow, ma il workflow sta aspettando il "rientro" della chiamata verso l'host. Ovviamente no! La richiesta di far scattare un evento nel workflow, sbloccando la HandleExternalEventActivity, è intercettata dall'ExchangeDataService (servizio di WF Runtime preposto a gestire la comunicazione tra l'host e il workflow) ed è accodata su una coda che verrà gestita solo nel momento in cui il workflow sarà "pronto". In pratica mettendo un po' di tracing nel codice avremo una sequenza di questo tipo:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;font color="#ff0000"&gt;Pre-Method Invoke - Thread Id: 6 - Physical Thread Id 1128&lt;/font&gt;  &lt;li&gt;&lt;font color="#ff0000"&gt;Method Invoking - Thread Id: 6 - Physical Thread Id 1128&lt;/font&gt;  &lt;li&gt;&lt;font color="#0000a0"&gt;Method Invoked - Thread Id: 6 - Physical Thread Id 1128&lt;/font&gt;  &lt;li&gt;&lt;font color="#0000a0"&gt;Event Invoking - Thread Id: 6 - Physical Thread Id 1128&lt;/font&gt;  &lt;li&gt;&lt;font color="#0000a0"&gt;OnTestEvent Invoked - Thread Id: 6 - Physical Thread Id 1128&lt;/font&gt;  &lt;li&gt;&lt;font color="#ff0000"&gt;Post-Method Invoke - Thread Id: 6 - Physical Thread Id 1128&lt;/font&gt;  &lt;li&gt;&lt;font color="#ff0000"&gt;Event Invoked - Thread Id: 6 - Physical Thread Id 1128&lt;/font&gt;  &lt;li&gt;&lt;font color="#ff0000"&gt;Post-Event Invoke - Thread Id: 6 - Physical Thread Id 1128&lt;/font&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;In rosso sono i trace da dentro il workflow, mentre in blu i trace nell'host. Notate che tutte le righe sono relative allo stesso thread e che l'evento scatta (penultima riga) nel workflow, solo dopo che l'esecuzione del metodo dell'host è stata completata.&lt;/p&gt; &lt;p&gt;Questo comportamento "sincrono" è appunto dovuto al fatto che lo scheduler utilizza un unico thread per l'esecuzione del workflow. &lt;/p&gt; &lt;p&gt;Vediamo ora che succede con un workflow a stati, anziché sequenziale. Immaginiamo di avere il seguente flusso&amp;nbsp;a stati:&lt;/p&gt; &lt;p&gt;&lt;img src="http://devlab.devleap.it/PaoloPi/Images/State-FW-Init-01.png"&gt; &lt;/p&gt; &lt;p&gt;La StateInitializationActivity dello stato iniziale si limita, per brevità,&amp;nbsp;a rimandare il flusso nello stato successivo.&lt;/p&gt; &lt;p&gt;&lt;img src="http://devlab.devleap.it/PaoloPi/Images/State-FW-NoInit-02.png"&gt; &lt;/p&gt; &lt;p&gt;Da qui la StateInitializationActivity dello stato "IntermediateState" chiama l'host del flusso con una CallExternalMethodActivity, oltre a tracciare alcune informazioni a fini di debug.&lt;/p&gt; &lt;p&gt;&lt;img src="http://devlab.devleap.it/PaoloPi/Images/State-FW-Init-02.png?a=1"&gt; &lt;/p&gt; &lt;p&gt;Da qui il codice che viene invocato nell'host richiama il flusso, come spiegavo all'inizio del post. L'evento richiamato dall'host è proprio quello per cui sta in attesa l'evento eventDrivenActivity1 all'interno dello stato "IntermediateState".&lt;/p&gt; &lt;p&gt;&lt;img src="http://devlab.devleap.it/PaoloPi/Images/State-FW-Init-03.png"&gt; &lt;/p&gt; &lt;p&gt;&lt;strong&gt;Qui arriva il bello!&lt;/strong&gt; Ci aspetteremmo un comportamento analogo a quello del flusso sequenziale: la coda prende in carico l'evento e quando il controllo torna al flusso la gestione riprende, proprio dall'evento. Invece no! Siamo nello fase di inizializzazione dello stato "IntermediateState" e le code dei suoi eventi non sono ancora state attivate, perchè potrebbe essere prematuro ricevere eventi senza che lo stato sia completamente inizializzato. Infatti in questo caso ecco il tracing estratto dal log.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;font color="#ff0000"&gt;Pre-Method Invoking - Thread Id: 7 - Physical Thread Id 4964&lt;/font&gt;&lt;/li&gt; &lt;li&gt;&lt;font color="#ff0000"&gt;Method Invoking - Thread Id: 7 - Physical Thread Id 4964&lt;/font&gt;&lt;/li&gt; &lt;li&gt;&lt;font color="#004080"&gt;Method Invoked - Thread Id: 7 - Physical Thread Id 4964&lt;/font&gt;&lt;/li&gt; &lt;li&gt;&lt;font color="#004080"&gt;Event Invoking - Thread Id: 7 - Physical Thread Id 4964&lt;/font&gt;&lt;/li&gt; &lt;li&gt;&lt;font color="#004080"&gt;OnTestEvent Invoked - Thread Id: 7 - Physical Thread Id 4964&lt;/font&gt;&lt;/li&gt; &lt;li&gt;&lt;font color="#004080"&gt;A first chance exception of type &lt;strong&gt;'System.Workflow.Activities.EventDeliveryFailedException'&lt;/strong&gt; occurred in System.Workflow.Activities.dll&lt;br&gt;Exception - Thread Id: 7 - Physical Thread Id 4964&lt;br&gt;Event "TestEvent" on interface type "Test_WF_Events.ICommunication" for instance id "53b2d8c4-2cd0-4f66-a6b8-07b9b963332b" cannot be delivered.&lt;br&gt;A first chance exception of type 'System.Workflow.Activities.EventDeliveryFailedException' occurred in Use-Test-WF-Events.exe&lt;/font&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Al solito il log rosso proviene dal workflow, mentre il log blu riguarda l'host. Come si vede ci prendiamo un bel EventDeliveryFailedException!&lt;br&gt;La InnerException ci spiega che si tratta in realtà di un errore di comunicazione perché l'evento TestEvent non può essere notificato (cannot be delivered).&lt;/p&gt; &lt;p&gt;Cercando con Google potreste trovare suggerimenti che consigliano di utilizzare un bel QueueUserWorkItem del ThreadPool per far scattare l'evento nel workflow. In pratica:&lt;/p&gt; &lt;p&gt;&lt;em&gt;&lt;font color="#008080"&gt;ThreadPool.QueueUserWorkItem(delegate(Object args) { OnTestEvent((ExternalDataEventArgs)args); }, e);&lt;/font&gt;&lt;/em&gt; &lt;p&gt;invece di: &lt;p&gt;&lt;em&gt;&lt;font color="#008080"&gt;OnTestEvent(e);&lt;/font&gt;&lt;/em&gt;&lt;/p&gt; &lt;p&gt;A prima vista sembrerebbe corretto, perché accodando l'invocazione dell'evento sul ThreadPool diamo un po' di "respiro" al thread che sta eseguendo l'istanza di workflow, così da consentirgli di uscire dall'host e rientrare nel flusso. &lt;strong&gt;Purtroppo però si tratta di una soluzione non corretta!&lt;/strong&gt; Infatti mettere la notifica dell'evento nel ThreadPool sposta solo il problema. In alcuni casi infatti tutto funzionerà a meraviglia,&amp;nbsp;in altri avremo comunque un errore, ma di natura diversa. Dipende dal carico della CPU o delle CPU. Infatti su sistemi multiprocessore il problema si enfatizza, perché abbiamo più cicli macchina a disposizione ed è più facile che il ThreadPool evada la richiesta di notifica dell'evento _prima_ che il thread rientri nel workflow. Per verificare sistematicamente il problema è sufficiente mettere una bella Thread.Sleep dopo l'accodamento dell'evento nel ThreadPool, per prolungare la permanenza del thread del workflow nel codice host.&lt;/p&gt; &lt;p&gt;&lt;em&gt;&lt;font color="#008080"&gt;&lt;em&gt;&lt;font color="#008080"&gt;ThreadPool.QueueUserWorkItem(delegate(Object args) { OnTestEvent((ExternalDataEventArgs)args); }, e);&lt;br&gt;&lt;/font&gt;&lt;/em&gt;&lt;/font&gt;&lt;/em&gt;&lt;em&gt;&lt;font color="#008080"&gt;Thread.Sleep(TimeSpan.FromSeconds(15));&lt;/font&gt;&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Eccoci! A questo punto abbiamo creato un mostro :-) ! Ad ogni giro il workflow ci dirà che non è in grado di evadere l'evento e capiremo che la vera ragione è che le code sono appunto "disabled" come spiegavo alcune righe più sopra. Ecco l'errore:&lt;/p&gt; &lt;p&gt;&lt;font color="#ff0000"&gt;Queue 'Message Properties Interface Type:Test_WF_Events.ICommunication Method Name:TestEvent CorrelationValues:' is not enabled.&lt;/font&gt;&lt;/p&gt; &lt;p&gt;Il ragionamento fila. Infatti se guardiamo con .NET Reflector possiamo notare che ad un certo punto il metodo SafeEnqueueEvent della classe WorkflowQueuingService verifica se le code sono enabled e se non lo sono scatena proprio questo tipo di&amp;nbsp;eccezione.&lt;/p&gt; &lt;p&gt;&lt;font color="#008080"&gt;// [... omissis ...]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font color="#008080"&gt;if (!queueState.Enabled)&lt;br&gt;{&lt;/font&gt;&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font color="#008080"&gt;throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, ExecutionStringManager.QueueNotEnabled, new object[] { queueName }));&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;&lt;font color="#008080"&gt;}&lt;br&gt;queueState.Messages.Enqueue(item);&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font color="#008080"&gt;// [... omissis ...]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Come fare quindi? Possiamo osservare che tutti gli eventi che scattano dall'host verso il workflow richiedono un EventArgs particolare, di tipo ExternalDataEventArgs o da esso derivato. Questa classe prevede una proprietà WaitForIdle che fa proprio al caso nostro. Infatti sempre con .NET Reflector possiamo notare che l'evento EventHandler della classe&amp;nbsp;WorkflowMessageHandler al suo interno verifica questa proprietà:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font color="#008080"&gt;// [... omissis ...]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font color="#008080"&gt;if (eventArgs.WaitForIdle)&lt;br&gt;{&lt;br&gt;wfInstance.EnqueueItemOnIdle(queueName, message, pendingWork, obj);&lt;br&gt;}&lt;br&gt;else&lt;br&gt;{&lt;br&gt;wfInstance.EnqueueItem(queueName, message, pendingWork, obj);&lt;br&gt;}&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font color="#008080"&gt;// [... omissis ...]&lt;/font&gt; &lt;p&gt;Nel caso in cui sia asserita, anziché evadere subito l'evento, lo accoderà in attesa che il flusso diventi Idle. In questo modo il flusso avrà tutto il tempo di concludere la chiamata all'host, qualunque sia il tempo richiesto, per poi passare la palla all'evento. Ecco il log delle fasi, nel caso in cui impostiamo correttamente il flag WaitOnIdle a true. &lt;ul&gt; &lt;li&gt;&lt;font color="#ff0000"&gt;Pre-Method Invoking - Thread Id: 10 - Physical Thread Id 3248&lt;/font&gt;&lt;/li&gt; &lt;li&gt;&lt;font color="#ff0000"&gt;Method Invoking - Thread Id: 10 - Physical Thread Id 3248&lt;/font&gt;&lt;/li&gt; &lt;li&gt;&lt;font color="#004080"&gt;Method Invoked - Thread Id: 10 - Physical Thread Id 3248&lt;/font&gt;&lt;/li&gt; &lt;li&gt;&lt;font color="#004080"&gt;Event Invoking - Thread Id: 10 - Physical Thread Id 3248&lt;/font&gt;&lt;/li&gt; &lt;li&gt;&lt;font color="#004080"&gt;OnTestEvent Invoked - Thread Id: &lt;strong&gt;12&lt;/strong&gt; - Physical Thread Id &lt;strong&gt;3176&lt;/strong&gt;&lt;/font&gt;&lt;/li&gt; &lt;li&gt;&lt;font color="#ff0000"&gt;Post-Method Invoked - Thread Id: 10 - Physical Thread Id 3248&lt;/font&gt;&lt;/li&gt; &lt;li&gt;&lt;font color="#ff0000"&gt;Event Invoked - Thread Id: 12 - Physical Thread Id 3176&lt;/font&gt;&lt;/li&gt; &lt;li&gt;&lt;font color="#ff0000"&gt;Post-Event Invoked - Thread Id: 12 - Physical Thread Id 3176&lt;/font&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Notate che in questo caso c'è il cambio di thread (a causa dell'accodamento nel ThreadPool) e che il giro si chiude correttamente. Rimane comunque consigliabile accodare nel ThreadPool l'evento di callback per non bloccare il codice chiamante, anche perché senza questo passaggio avremmo comunque un errore di delivery verso il nostro evento, in quanto andremmo a creare un deadlock. Infatti la situazione diventerebbe la seguente:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Il thread corrente accoda un evento, in sincrono, che aspetta che il flusso sia Idle prima di scattare&lt;/li&gt; &lt;li&gt;Il flusso, con quello stesso thread, sta aspettando che il metodo che esegue il codice precedente finisca, per poi completare l'inizializzazione dello stato e mettersi Idle&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Risultato: deadlock! Quindi avremmo una EventDeliveryFailedException.&lt;/p&gt; &lt;p&gt;Ok quindi in questi casi occorre:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Definire WaitOnIdle = true&lt;/li&gt; &lt;li&gt;Chiamare l'evento in un thread secondario, ad esempio usando il ThreadPool&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Nessuno dei due step precedenti risolve, da solo, il problema. Servono entrambi.&lt;/p&gt; &lt;p&gt;L'unica altra alternativa che abbiamo, ma non cambia il risultato finale, è definire nello stato "IntermediateState" un evento ad inizio immediato, tramite una DelayActivity con TimeoutDuration impostata a 0 (zero), anziché una StateInitializationActivity. In questo modo infatti le code del flusso, relative agli eventi dello stato, verrebbero attivate prima della chiamata all'host. In questo caso non è strettamente necessario impostare WaitOnIdle a true perché comunque il thread che evade i messaggi in coda è uno solo, quindi comunque dovremmo aspettare la fine del primo evento per poter proseguire. &lt;/p&gt; &lt;p&gt;Ecco lo schema dell'ultimo caso.&lt;/p&gt; &lt;p&gt;&lt;img src="http://devlab.devleap.it/PaoloPi/Images/State-FW-NoInit-01.png"&gt; &lt;/p&gt; &lt;p&gt;&lt;img src="http://devlab.devleap.it/PaoloPi/Images/State-FW-NoInit-02.png"&gt; &lt;img src="http://devlab.devleap.it/PaoloPi/Images/State-FW-NoInit-03.png"&gt;&lt;img src="http://devlab.devleap.it/PaoloPi/Images/State-FW-NoInit-04.png"&gt;&lt;/p&gt; &lt;p&gt;Direi comunque che la soluzione più idonea è quella di utilizzare il ThreadPool o comunque un thread secondario e il WaitOnIdle impostato a true, sfruttando - se serve - lo StateInitialization.&lt;/p&gt; &lt;p&gt;Per chi volesse "divertirsi" con queste cose &lt;a href="http://devlab.devleap.it/PaoloPi/WF/Test-WF-Events.zip"&gt;rendo disponibile&lt;/a&gt; il progettino "grezzo" che ho usato&amp;nbsp;per approfondire&amp;nbsp;l'argomento. C'è da giocare un po' con i commenti&amp;nbsp;nel codice per abilitare e verificare il comportamento di WF nei&amp;nbsp;vari casi... se non torna qualcosa &lt;a href="mailto:paolo@devleap.it"&gt;potete mandarmi una email&lt;/a&gt;.&amp;nbsp;&lt;/p&gt; &lt;p&gt;Spero di aver dato una fotografia della situazione utile ad altri e vi rimando alle sessioni su WF che terrò alla nostra &lt;a title="DevCon 2007" href="http://devcon2007.devleap.com/" target="_blank"&gt;DevCon 2007&lt;/a&gt; per ulteriori dettagli sul funzionamento di Windows Workflow Foundation, anche in progetti reali.&lt;/p&gt;&lt;img src="http://blogs.devleap.com/aggbug.aspx?PostID=16629" width="1" height="1"&gt;</description><category domain="http://blogs.devleap.com/paolo/archive/tags/.NET+3.0/default.aspx">.NET 3.0</category><category domain="http://blogs.devleap.com/paolo/archive/tags/WF/default.aspx">WF</category></item></channel></rss>