<?xml version="1.0" encoding="iso-8859-15"?><feed version="0.3" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns="http://purl.org/atom/ns#" xml:lang="it-it"><title>Ricciolo.NET - Il blog di Cristian "Ricciolo" Civera</title><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/" /><tagline type="text/html">Ricciolo.NET - Il blog di Cristian &quot;Ricciolo&quot; Civera</tagline><id>http://blogs.aspitalia.com/ricciolo/</id><generator url="http://feed.aspitalia.com/" version="ASPItalia.com">feed.ASPItalia.com 'Weyoh' 4.8.501</generator><author><name>Ricciolo.NET - Il blog di Cristian &quot;Ricciolo&quot; Civera</name><url>http://blogs.aspitalia.com/ricciolo/</url></author><modified>2008-05-09T22:01:30+01:00</modified><entry><title>Styles Explorer: decompilatore BAML</title><id>http://blogs.aspitalia.com/ricciolo/post2263/Styles-Explorer-Decompilatore-BAML.aspx</id><created>2008-04-04T23:57:00+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2263' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Vi ricordate quando vi &lt;a href=&quot;http://blogs.aspitalia.com/ricciolo/post2124/Come-Fatto-Formato-BAML-WPF.aspx&quot;&gt;parlai&lt;/a&gt; di come viene compilato lo &lt;strong&gt;XAML&lt;/strong&gt; e quale struttura ha? Beh &#232; un po' che avevo pi&#249; o meno pronta quella classe e mancava qualcosa per usarla a dovere. Portando avanti a singhiozzo il progetto, finalmente posso farvi vedere qualcosa di &lt;strong&gt;Styles Explorer&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;E' uno strumento che ti permette di aprire qualsiasi DLL, enumerare le risorse &lt;strong&gt;BAML&lt;/strong&gt; che contiene e decompilare (se ce la fa) fornendo l'XML. E' principalmente improntato sui &lt;strong&gt;ResourceDictionary&lt;/strong&gt;, perci&#242; &#232; in grado di fornire un'anteprima di un oggetto o di uno style.&lt;/p&gt;&lt;p&gt;Siccome i tempi cambiano, invece degli screenshot vi metto un bel filmato&lt;/p&gt;&lt;embed pluginspage=&quot;http://macromedia.com/go/getflashplayer&quot; src=&quot;http://images.video.msn.com/flash/soapbox1_1.swf&quot; width=&quot;432&quot; height=&quot;364&quot; type=&quot;application/x-shockwave-flash&quot; flashvars=&quot;c=v&amp;amp;v=184a6290-13ec-4aa3-8c37-51e85d430303&amp;amp;ifs=true&amp;amp;fr=msnvideo&amp;amp;mkt=en-US&amp;amp;brand=&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; base=&quot;http://images.video.msn.com&quot; quality=&quot;high&quot; /&gt;&lt;/embed /&gt;&lt;br /&gt;&lt;a title=&quot;Styles Explorer&quot; href=&quot;http://video.msn.com/video.aspx?vid=184a6290-13ec-4aa3-8c37-51e85d430303&quot; target=&quot;_new&quot;&gt;Video: Styles Explorer&lt;/a&gt;&lt;p&gt;Ovviamente il progetto &#232; ancora in corso e va migliorato, ma fino adesso mi son divertito a fare alcune cose carine, come usare pi&#249; AppDomain per isolare il caricamento degli assembly, o fare una nuova message pump solo per la preview cos&#236; da evitare problemi con il resto dell'applicazione.&lt;/p&gt;&lt;p&gt;Ah dimenticavo, potete installarlo da &lt;a href=&quot;http://ricciolo.lab.aspitalia.com/StylesExplorer/Ricciolo.StylesExplorer.application&quot;&gt;qua&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework/&quot; rel=&quot;tag&quot;&gt;.NET Framework&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.0/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.0&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.5/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.5&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/Windows_Presentation_Foundation/&quot; rel=&quot;tag&quot;&gt;Windows Presentation Foundation&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/XAML/&quot; rel=&quot;tag&quot;&gt;XAML&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2263/Styles-Explorer-Decompilatore-BAML.aspx"/><issued>2008-04-04T23:57:00+01:00</issued><modified>2008-04-04T23:57:00+01:00</modified><slash:comments>2</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2263/Styles-Explorer-Decompilatore-BAML.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2263.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2263</trackback:ping></entry><entry><title>Le evoluzioni del Web che non capisco</title><id>http://blogs.aspitalia.com/ricciolo/post2256/Evoluzioni-Web-Capisco.aspx</id><created>2008-03-18T17:51:00+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2256' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Chi mi conosce sa che non sono un gran simpatizzante di &lt;strong&gt;AJAX&lt;/strong&gt; e riconoscendo che in effetti serve qualcosa di pi&#249; del buon vecchio HTML, trovo Silverlight decisamente una soluzione migliore. Ma non &#232; di questa moda che voglio parlare, ma bens&#236; di &lt;strong&gt;REST&lt;/strong&gt; e &lt;strong&gt;POX&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;Con il primo termine si intende il voler sfruttare a pieno le capacit&#224; di &lt;strong&gt;HTTP&lt;/strong&gt;, mediante i suoi method, per ampliare l'applicazione web e fornire servizi aggiuntivi usufruibili al di fuori dell'HTML e della semplice navigazione. In pratica, siccome esistono i metodi &lt;strong&gt;GET&lt;/strong&gt;, &lt;strong&gt;POST&lt;/strong&gt;, &lt;strong&gt;PUT&lt;/strong&gt; e &lt;strong&gt;DELETE&lt;/strong&gt; si &#232; pensato di sfruttarli per eseguire le classiche operazioni CRUD, magari aggiugendo dei parametri nell'URI o nel contenuto della richiesta. Tutto questo ovviamente esiste da sempre, ma veniva marginalmente sfruttato e solo ora, e ben venga, siti come Amazon, Google, Live, ecc permettono di interrogare e di usufruire dei loro servizi mediante REST.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;POX&lt;/strong&gt; invece vuol dire Plain Old XML e in pratica vuol dire usare XML semplice senza fronzoli, da utilizzare nelle richieste o risposte REST.&lt;/p&gt;&lt;p&gt;Cosa non mi piace di tutto questo? Il fatto che si sta reinventando la ruota. Per esempio, chi espone operazioni REST si trova a dover fornire della documentazione per spiegare come chiamare le varie operazioni, come dev'essere passato l'XML e spesso in maniera superficiale, limitandosi ad un esempio di XML o ad un esempio di parametro in query string. Beh a tutto questo qualcuno ci aveva gi&#224; pensato e vedendo che non era sufficiente aveva pensato ai &lt;strong&gt;WebService&lt;/strong&gt;, a &lt;strong&gt;SOAP&lt;/strong&gt;, ai consorzi per renderli i pi&#249; interoperabili possibili. Per XML esistono gli schema &lt;strong&gt;XSD&lt;/strong&gt; che sono molto pi&#249; completi, mentre per conoscere quali operazioni espone un servizio c'&#232; &lt;strong&gt;WSDL&lt;/strong&gt; e &lt;strong&gt;WS-Metadata Exchange&lt;/strong&gt;. Senza contare che con framework come &lt;strong&gt;WCF&lt;/strong&gt; basta semplicemente fare un &amp;quot;Add Service reference&amp;quot; e ci si pu&#242; persino permettere di ignorare questi linguaggi e di esporre della documentazione aggiuntiva.&lt;/p&gt;&lt;p&gt;E' vero che non tutti fanno applicazioni enterprise ed usare WCF/WebService pu&#242; sembrare un carro armato per uccidere le mosche, ma sono del parere che alcune problematiche sono presenti anche in semplici siti web. Tra questi il gi&#224; citato, come chiamare un'operazione, ma anche quali errori mi pu&#242; eventualmente dare e come li gestisco. Poi man mano ci sono altri aspetti, come l'autenticazione, spesso affidata ad un token rilasciato da chi espone il servizio da inserire nella querystring, mentre in &lt;strong&gt;WS-*&lt;/strong&gt; tutto questo &#232; gi&#224; definito. Sono inoltre definiti come rendere le operazioni sicure, criptate, transazionali, come gestire le policy ed inviare file di grosse dimensioni. Ovviamente se tutto questo non serve basta non abilitarlo e l'XML resta contenuto, senza offenderlo chiamandolo POX :-).&lt;/p&gt;&lt;p&gt;E' per questo che storto un po' il naso e che il diffondersi di questi termini sia pi&#249; dovuto o ad ignoranza su certe tecnologie (almeno io so il loro nome :-) ) oppure ad una pigrizia nell'affrontarle ed impararle. Detto questo, sicuramente ci sono ambiti in cui una normale richiesta GET basta e avanza; l'importante che vengano valutate anche le altre strade e che non venga coniato qualche nuovo termine o nuova era del web.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/Silverlight/&quot; rel=&quot;tag&quot;&gt;Silverlight&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/XAML/&quot; rel=&quot;tag&quot;&gt;XAML&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2256/Evoluzioni-Web-Capisco.aspx"/><issued>2008-03-18T17:51:00+01:00</issued><modified>2008-03-18T17:51:00+01:00</modified><slash:comments>11</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2256/Evoluzioni-Web-Capisco.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2256.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2256</trackback:ping></entry><entry><title>Un'occhiata a Silverlight 2.0</title><id>http://blogs.aspitalia.com/ricciolo/post2248/Unocchiata-Silverlight-2.0.aspx</id><created>2008-03-08T17:29:00+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2248' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Come probabilmente &lt;a href=&quot;http://www.aspitalia.com/focuson/1027/Rilasciata-Ufficialmente-Versione-Beta1-Silverlight-2.0.aspx&quot;&gt;saprete&lt;/a&gt; &#232; stata rilasciata la beta &lt;strong&gt;Silverlight 2.0&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;Ovviamente da fan di &lt;strong&gt;WPF&lt;/strong&gt; non ho resistito dal provarla subito. Sinceramente, delle scorse preview ero rimasto un po' deluso, poich&#233; conoscendo WPF mi rendevo conto di quante cose mancassero diventando cos&#236; frustrante giocarci. Beh invece con Silverlight 2.0 mi ritengo soddisfatto e entusiasta come un bambino che scarta i regali a Natale :-D&lt;/p&gt;&lt;p&gt;Per prima cosa il setup installa runtime, template per &lt;strong&gt;Visual Studio 2008&lt;/strong&gt; e SDK. Una parte del SDK &#232; rivolta al server e l'altra al client.&lt;/p&gt;&lt;p&gt;Lato server una nuova System.Web.Silverlight.dll contiene i controlli &lt;strong&gt;Silverlight&lt;/strong&gt; e &lt;strong&gt;MediaPlayer&lt;/strong&gt;. Il primo semplicemente crea il markup per istanziare il plugin, include il codice JavaScript e non &#232; pi&#249; necessario includere script esterni ecc. MediaPlayer &#232; un&#160;controllo pi&#249; evoluto che permette con due click di inserire un player di video con tanto di&#160;marcatori e capitoli basandosi su&#160;Silverlight. Il tutto completamente skinnabile, con&#160;una decina di skin gi&#224; presenti nel SDK. Molto maschio.&lt;/p&gt;&lt;p&gt;Lato client l'architettura &#232;&#160;rimasta invariata e il runtime, di soli 4,3MB,&#160;&#232;&#160;installato in %ProgramFiles%\Microsoft Silverlight\2.0.30226.2. Rispetto alla alpha abbiamo in pi&#249; System.ServiceModel (WCF quindi) con &lt;strong&gt;BasicHttpBinding&lt;/strong&gt;, supporto a &lt;strong&gt;REST&lt;/strong&gt; e&#160;&lt;strong&gt;JSON&lt;/strong&gt;. L'assembly System.Windows &#232; stato ampliato con altre classi base con niente popo di meno che: StackPanel, Grid, Border, TextBox, ItemsControl (i principali).&lt;/p&gt;&lt;p&gt;Incredibile, c'&#232; la classe &lt;strong&gt;Binding&lt;/strong&gt; con IValueConverter, BindingMode, Source, ma nessun altra tipologia di binding. In molti aspetti Silverlight assomiglia da fuori a WPF, ma dentro l'implementazione &#232; decisamente diversa, tendente al risparmio (non poteva essere diversamente). I controlli sono basati su &lt;strong&gt;DependencyProperty&lt;/strong&gt; (anche Attached Property), ma non &#232; presente&#160;nessun meccanismo di triggering o metadati aggiuntivi, mentre gli eventi invece sono quelli normali del CLR; quindi niente Attached Event, niente bubbling o tunneling ed eventi di preview.&lt;/p&gt;&lt;p&gt;I controlli si basano su &lt;strong&gt;Template&lt;/strong&gt; che vengono caricati tramite &lt;strong&gt;Style&lt;/strong&gt; avente come TargetType il tipo del controllo da personalizzare. Gli Style non hanno trigger, quindi nel metodo &lt;strong&gt;ApplyTemplate&lt;/strong&gt; ogni controllo cerca elementi nel template dal nome prefissato&#160;(es: RootElement), ne intercettono gli eventi e interagiscono in base a quest'ultimi. Questa tecnica esiste in modo identico anche in WPF, ma si usa raramente preferendo l'uso di trigger in modo da legare il meno possibile il codice al markup. Continuando con il paragone con WPF, niente Command, CollectionView e WeakEvent.&lt;/p&gt;&lt;p&gt;Tutto sommato quindi, le cose che si potevano implementare sono state copiate da WPF e questo non pu&#242; farmi che piacere&#160;:-), ma ovviamente per non esagerare nella dimensione degli assembly &#232; stato sacrificato qualcosa.&lt;/p&gt;&lt;p&gt;Da Visual Studio o Blend 2.5 possiamo creare un progetto Silverlight 2.0 e rispetto a prima, si sviluppa una specie di class library avente gi&#224; pronti i file App.xaml, che &#232; l'entry point, e un file Page.xaml: lo &lt;strong&gt;UserControl&lt;/strong&gt; principale. Ovviamente hanno il relativo code-behind dove possiamo scrivere in C# 3.0 o VB 9.&lt;br /&gt;Il risultato della compilazione &#232; un file &lt;strong&gt;.xap&lt;/strong&gt;, l'unico file da distribuire,&#160;che&#160;&#232; un file .zip contenente un file di metadati,&#160;i file che abbiamo incluso nel progetto con target Content e&#160;la nostra dll compilata. Quest'ultima contiene nelle risorse i file XAML, ma non compilati in &lt;strong&gt;BAML&lt;/strong&gt; (diversamente da WPF). Probabilmente questa scelta &#232; dovuta al fatto che l'ottimizzazione di caricamento del markup &#232; stata ritenuta sacrificabile, mentre la compressione &#232; gi&#224; ottenuta grazie allo ZIP.&lt;/p&gt;&lt;p&gt;Per ultimo una cosa inaspettata: nel progetto di Visual Studio troveremo referenziati altre dll che verranno poi incluse nel file xap. Queste&#160;normalmetne sono: &lt;strong&gt;System.Windows.Controls&lt;/strong&gt; e &lt;strong&gt;System.Windows.Controls.Extended&lt;/strong&gt;. Queste dll, pi&#249; altre,&#160;si trovano normalmente nella cartella del SDK (C:\Program Files\Microsoft SDKs\Silverlight\v2.0\Libraries\Client) e non sono incluse nel setup di Silverlight. Peccato che quest'altre 18 dll contengano: &lt;strong&gt;Ruby&lt;/strong&gt;, &lt;strong&gt;Python&lt;/strong&gt;, &lt;strong&gt;Managed JScript&lt;/strong&gt;, le classi Syndacation RSS/Atom di WCF, &lt;strong&gt;Linq To Xml&lt;/strong&gt;, controlli come Thumb (per il drag&amp;amp;drop), Button, CheckBox, ListBox, RadioButton, Slider, ScrollBar, ScrollViewer, ToolTip, ToggleButton, DataGrid, Calendar, DateTimePicker, GridSplitter, WatermarkedTextBox.&lt;/p&gt;&lt;p&gt;Prima di tutto stupisce che ci siano controlli che WPF non&#160;ha e sia Silverlight il primo ad implementarli, ma soprattutto ecco spiegato perch&#233; il runtime &#232; piccolo. Infatti tutte le altre dll le mandiamo noi all'utente inglobandole nel file xap. Cos&#236; l'installazione del plugin&#160;&#232; piccola,&#160;mentre l'utente navigando su pi&#249; siti si ritrova a scaricare solo le dll che effettivamente l'applicazione usa, con il rischio ovviamente di scaricare&#160;pi&#249; volte la stessa dll in pacchetti diversi. Furbini vero? :-D&lt;/p&gt;&lt;p&gt;Non l'ho ancora guardato benissimo, ma Silverlight cos&#236; mi piace decisamente e non ha rivali sul web. Se volete vederlo all'opera potete venire al &lt;a href=&quot;http://www.aspitalia.com/eventi/12/Real-Code-Launch-2008-Roma.aspx&quot;&gt;Real Code Launch&lt;/a&gt; che terremo a Roma. Dovete assolutamente venire; chi c'&#232;, c'&#232;, chi non c'&#232;... eh non c'&#232;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.0/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.0&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/Microsoft_Expression/&quot; rel=&quot;tag&quot;&gt;Microsoft Expression&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/Silverlight/&quot; rel=&quot;tag&quot;&gt;Silverlight&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/Silverlight_-_animazioni/&quot; rel=&quot;tag&quot;&gt;Silverlight - animazioni&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/Silverlight_2.0/&quot; rel=&quot;tag&quot;&gt;Silverlight 2.0&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/Windows_Presentation_Foundation/&quot; rel=&quot;tag&quot;&gt;Windows Presentation Foundation&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/XAML/&quot; rel=&quot;tag&quot;&gt;XAML&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2248/Unocchiata-Silverlight-2.0.aspx"/><issued>2008-03-08T17:29:00+01:00</issued><modified>2008-03-08T17:29:00+01:00</modified><slash:comments>4</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2248/Unocchiata-Silverlight-2.0.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2248.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2248</trackback:ping></entry><entry><title>Ho aperto un nuovo blog</title><id>http://blogs.aspitalia.com/ricciolo/post2227/Aperto-Blog.aspx</id><created>2008-02-16T18:34:00+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2227' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Probabilmente vi domanderete perch&#233; abbia aperto un altro blog visto che a mala pena scrivo su questo. Semplice, per scrivere le mie esperienze in inglese. Quindi niente paura, le tematiche sono le stesse e&#160;se sfortunatamente leggete gi&#224; questo blog resterete sempre aggiornati:&#160;tutto quello che scriver&#242; in inglese verr&#224; scritto in italiano e forse anche viceversa.&lt;/p&gt;&lt;p&gt;Il blog si trova &lt;a href=&quot;http://blogs.windowsclient.net/RiccioloCristian/&quot;&gt;qua&lt;/a&gt;, aggregato sul sito di &lt;a href=&quot;http://www.windowsclient.net&quot; target=&quot;_blank&quot;&gt;windowsclient.net&lt;/a&gt;.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2227/Aperto-Blog.aspx"/><issued>2008-02-16T18:34:00+01:00</issued><modified>2008-02-16T18:34:00+01:00</modified><slash:comments>2</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2227/Aperto-Blog.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2227.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2227</trackback:ping></entry><entry><title>DirectShow e WPF: soluzione finale</title><id>http://blogs.aspitalia.com/ricciolo/post2213/DirectShow-WPF-Soluzione-Finale.aspx</id><created>2008-01-28T17:20:37+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2213' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;o quasi... :-) Nel precedente &lt;a href=&quot;http://blogs.aspitalia.com/ricciolo/post2210/sorgenti-custom-mediaelement-wpf.aspx&quot; onclick=&quot;blankUrl(this.href); return false;&quot;&gt;post&lt;/a&gt; ho parlato delle problematiche e possibili soluzioni per mostrare sorgenti video personalizzate in &lt;strong&gt;WPF&lt;/strong&gt;. Ho accennato ad una possibile terza soluzione e sebbene non perfetta la reputo la migliore.&lt;/p&gt; &lt;p&gt;Partiamo dal risultato. Nella figura sottostante potete ammirare un esemplare maschio homo sapiens sapiens:&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://blogs.aspitalia.com/img/ricciolo/directshowewpfsoluzionefinale_10201/camera_2.jpg&quot;&gt;&lt;img height=&quot;466&quot; alt=&quot;camera&quot; src=&quot;http://blogs.aspitalia.com/img/ricciolo/directshowewpfsoluzionefinale_10201/camera_thumb.jpg&quot; width=&quot;404&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;L'esempio &amp;#232; ottenuto usando come VisualBrush di un cubo 3D, un mio oggetto:&lt;/p&gt; &lt;p class=&quot;codebox&quot;&gt;&lt;code&gt;&amp;lt;ricciolo:WebcamElement Source=&amp;quot;webcam://WebcamElement/Video%20Camera&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Questa classe eredita da una classe base &lt;strong&gt;AdvancedMediaElement&lt;/strong&gt; (eredita dalla standard MediaElement) che offre le funzionalit&amp;#224; base per supportare qualsiasi grafo &lt;strong&gt;DirectShow&lt;/strong&gt;. Nello specifico, per l'intera applicazione uso una libreria Microsoft di nome &lt;a href=&quot;http://research.microsoft.com/sn/detours/&quot; onclick=&quot;blankUrl(this.href); return false;&quot;&gt;detours&lt;/a&gt; che permette di sovrascrivere le funzioni &lt;strong&gt;Win32&lt;/strong&gt; ed eventualmente chiamare la funzione originale. Per il mio scopo intercetto la chiamata a &lt;strong&gt;CoCreateInstance&lt;/strong&gt;, usata per instanziare gli oggetti &lt;strong&gt;COM&lt;/strong&gt;, e quando il MediaElement carica l'URL coercizzo il valore ad un file fisico vuoto creato al volo nella temp dir. &lt;strong&gt;Windows Media Player&lt;/strong&gt; carica DirectShow, crea il grafo e crea l'AsyncReader standard. Io che sono infame, mediante detours, restituisco un mio oggetto che implementa IAsyncReader e non presenta nessun pin. L'intelligent connect passa il nome del file &lt;strong&gt;IFileSourceFilter::Load&lt;/strong&gt; al mio filtro e poi si ferma, mentre quest'ultimo tramite callback notifica all'AdvancedMediaElement di caricare il grafo. Mediante l'associazione URI/istanza chiamo un metodo virtuale OnGraphLoad(IGraphBuilder graph) nella quale le varie implementazioni (nel mio caso WebcamElement) possono popolare il grafo con i fitri che vogliono lavorando via interop con l'ausilio di librerie tipo &lt;a href=&quot;http://directshownet.sourceforge.net/&quot; onclick=&quot;blankUrl(this.href); return false;&quot;&gt;DirectShowLib&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;La soluzione &amp;#232; in parte in C++ CLI, in parte in C#, &amp;#232; aperta ad altre implementazioni e non richiede nessuna registrazione di DLL (le detours sono inglobate nel mio assembly) o di protocol handler. L'unica nota dolente &amp;#232; quel finto file vuoto temporaneo che devo creare per costringere WMP ad usare DirectShow; se qualcune conosce quindi un'alternativa sar&amp;#242; ben contento di ascoltarla.&lt;/p&gt; &lt;p&gt;Presto sorgenti e applicazione di test nel lab&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2213/DirectShow-WPF-Soluzione-Finale.aspx"/><issued>2008-01-28T17:20:37+01:00</issued><modified>2008-01-28T17:20:37+01:00</modified><slash:comments>0</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2213/DirectShow-WPF-Soluzione-Finale.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2213.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2213</trackback:ping></entry><entry><title>Sorgenti custom per MediaElement di WPF</title><id>http://blogs.aspitalia.com/ricciolo/post2210/Sorgenti-Custom-MediaElement-WPF.aspx</id><created>2008-01-23T12:49:59+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2210' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;L'elemento &lt;strong&gt;MediaElement&lt;/strong&gt; &amp;#232; un gran bell'oggettino :-) Permette di mostrare e ascoltare video e audio, il tutto perfettamente integrato con WPF permettendoci di ridimensionarlo come ci pare, usarlo come brush, trasformarlo, applicare trasparenze, ecc...&lt;/p&gt; &lt;p&gt;L'unico problema &amp;#232; che al di l&amp;#224; di file su disco o uri http, non si pu&amp;#242; andare. Per esempio pu&amp;#242; essere utile usare come sorgente la webcam, un tuner TV o una fonte analogica esterna. Per ottenere ci&amp;#242; ci sono vari modi:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Usare l'elemento &lt;strong&gt;HwndSource&lt;/strong&gt; cos&amp;#236; da avere una finestra Win32. Tramite la propriet&amp;#224; Handle abbiamo il suo puntatore e possiamo quindi usare &lt;strong&gt;DirectShow&lt;/strong&gt; effettuando il rendering puntando la finestra con l'interfaccia &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/ms786984.aspx&quot; onclick=&quot;blankUrl(this.href); return false;&quot;&gt;IVideoWindow&lt;/a&gt;. Se vi interessa &amp;#232; disponibile &lt;a href=&quot;http://directshownet.sourceforge.net/&quot; onclick=&quot;blankUrl(this.href); return false;&quot;&gt;questo progetto&lt;/a&gt; pieno di classi interop per usare DirectShow in .NET. &lt;br /&gt;Questo approccio ha dei limiti dovuti al fatto che HwndSource &amp;#232; s&amp;#236; un elemento WPF, ma poich&amp;#233; contiene al suo interno una nuova finestra Win32 non permette di effettuare trasformazioni, trasparenze, ecc.&lt;/li&gt; &lt;li&gt;Costruire un protocol handler per un proprio schema (esempio webcam://qualcosa) che faccia uso di un source filter personalizzato per DirectShow. Questo &amp;#232; possibile perch&amp;#233; MediaElement utilizza al suo interno &lt;strong&gt;Windows Media Player&lt;/strong&gt; che a sua volta si basa su &lt;strong&gt;Windows Media Foundation&lt;/strong&gt; che a sua volta usa (se necessario) DirectShow.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Ho provato entrambi le modalit&amp;#224; e ovviamente la seconda &amp;#232; la migliore (esiste una terza che sto ancora sperimentando). Nella seconda ho scritto in C++ un source filter che implementa &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/ms785718.aspx&quot; onclick=&quot;blankUrl(this.href); return false;&quot;&gt;IFileSourceFilter&lt;/a&gt;, cos&amp;#236; da essere da essere chiamato per caricare il mio schema custom. Non entro troppo nei dettagli, ma &amp;#232; compito di WMP caricare il mio filtro e, una volta aggiunto al grafo DirectShow, renderizzare il pin video in uscita sfruttando l'&lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/ms786503(vs.85).aspx&quot; onclick=&quot;blankUrl(this.href); return false;&quot;&gt;Intelligent Connect&lt;/a&gt;. Questo sistema in pratica si mette a guardare i pin del filtro sorgente e prova le possibili combinazioni tra filtri di decodifica e di rendering fino a quando non riesce a mostrare il video e/o ad emettere il suono. In WPF il filtro sorgente quindi dipende dal protocol handler, mentre il rendering video viene effettuato mediante &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/ms694916(vs.85).aspx&quot; onclick=&quot;blankUrl(this.href); return false;&quot;&gt;Enhanced Video Renderer&lt;/a&gt;: un filtro nuovo e pi&amp;#249; evoluto che permette l'integrazione in WPF.&lt;/p&gt; &lt;p&gt;Nella mia prova ho usato il tipico filtro Ball presente nel SDK, costituito da un pin che restituisce uno stream video che mostra una palla rimbalzare. Una volta pronto il filtro, va poi registrato sia come dll, sia mappando lo schema custom al filtro. Possiamo poi usarlo sia in WMP che in GraphEdit (un tool per testare i filtri). Ecco uno screenshot:&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://blogs.aspitalia.com/img/ricciolo/sorgenticustompermediaelementdiwpf_9079/ball1.png&quot;&gt;&lt;img height=&quot;347&quot; alt=&quot;ball1&quot; src=&quot;http://blogs.aspitalia.com/img/ricciolo/sorgenticustompermediaelementdiwpf_9079/ball1_thumb.png&quot; width=&quot;400&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;A questo punto possiamo usare il filtro anche in WPF:&lt;/p&gt; &lt;p class=&quot;codebox&quot;&gt;&lt;code&gt;&amp;lt;MediaElement Source=&amp;quot;ball://test&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/p&gt; &lt;p&gt;E questo &amp;#232; il risultato che si ottiene applicandoci il tipico effetto riflesso, per far vedere che possiamo trattare il video come vogliamo:&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://blogs.aspitalia.com/img/ricciolo/sorgenticustompermediaelementdiwpf_9079/ball2.png&quot;&gt;&lt;img height=&quot;360&quot; alt=&quot;ball2&quot; src=&quot;http://blogs.aspitalia.com/img/ricciolo/sorgenticustompermediaelementdiwpf_9079/ball2_thumb.png&quot; width=&quot;250&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Quindi in teoria possiamo fare un pin che prenda lo stream da un grafo interno oppure possiamo fare un filtro senza pin, ma che sul metodo Load inserisce nel grafo un nuovo filtro sorgente (webcam, tuner ecc). Ci pensa poi l'intelligent connect ad ignorare il nostro filtro custom, proseguendo sull'altro da noi creato. Questa variante &amp;#232; stilisticamente meno carina, ma pi&amp;#249; semplice.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework/&quot; rel=&quot;tag&quot;&gt;.NET Framework&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.0/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.0&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.5/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.5&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/Windows_Presentation_Foundation/&quot; rel=&quot;tag&quot;&gt;Windows Presentation Foundation&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/XAML/&quot; rel=&quot;tag&quot;&gt;XAML&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2210/Sorgenti-Custom-MediaElement-WPF.aspx"/><issued>2008-01-23T12:49:59+01:00</issued><modified>2008-01-23T12:49:59+01:00</modified><slash:comments>1</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2210/Sorgenti-Custom-MediaElement-WPF.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2210.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2210</trackback:ping></entry><entry><title>Anonymous type di C# 3.0</title><id>http://blogs.aspitalia.com/ricciolo/post2197/Anonymous-Type-CSharp-3.0.aspx</id><created>2008-01-04T14:21:18+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2197' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Giocando con &lt;strong&gt;LINQ&lt;/strong&gt; avrete senz'altro usato gli anonymous type: quei tipi creati al volo per contenere varie informazioni. Poniamo questo semplice esempio:&lt;/p&gt; &lt;p class=&quot;colorato&quot;&gt;&lt;code&gt;var v = new {Language = &amp;quot;IT&amp;quot;, Age=30};&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Prima di tutto, v &amp;#232; visibile solo all'interno dello stack in cui l'abbiamo dichiarato. Quindi all'interno di una funzione o metodo, ma mai a livello di classe. Possiamo anche ritornarlo come valore da una funzione, ma potremmo limitarci a ritornare un tipo object generico e non potremmo fare riferimento al nome del tipo, facendo cast o quant'altro (se non via reflection, bleah bleah). Quindi ques'ultima opzione &amp;#232; fortemente sconsigliata.&lt;/p&gt; &lt;p&gt;Quando compiliamo, viene automaticamente generata una classe internal sealed dal nome f__AnonymousType[numero] sul namespace root. La classe eredita da Object definisce n propriet&amp;#224; e n campi per memorizzare i valori e dispone di un costruttore che accetta come parametri i valori da impostare sulle propriet&amp;#224;. Non c'&amp;#232; modo di cambiarne visibilit&amp;#224; ai tipi o ai membri, ne di rendere in sola lettura le propriet&amp;#224;. Questa classe ha la particolarit&amp;#224; di essere generica, nel senso che i tipi string e int delle propriet&amp;#224; Language e Age del nostro esempio, sono generici. Questo per evitare di creare copie della medesima classe. Quindi se utiliziamo nel medesimo assembly un anonymous type simile:&lt;/p&gt; &lt;p class=&quot;colorato&quot;&gt;&lt;code&gt;var v = new {Language = 1, Age=3d};&lt;/code&gt;&lt;/p&gt; &lt;p&gt;verr&amp;#224; utilizzata la medesima classe autogenerata, ma con generics argument diversi: int e double.&lt;/p&gt; &lt;p&gt;Tale classe inoltre sovrascrive ToString per mostrare facilmente il contenuto, Equals e GetHashCode cos&amp;#236; da rendere comparabile il tipo quando viene utilizzato, per esempio da LINQ To Objects:&lt;/p&gt; &lt;p class=&quot;colorato&quot;&gt;&lt;code&gt;[DebuggerHidden] &lt;br /&gt;public override string ToString() &lt;br /&gt;{ &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; StringBuilder builder = new StringBuilder(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; builder.Append(&amp;quot;{ Language = &amp;quot;); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; builder.Append(this.&amp;lt;Language&amp;gt;i__Field); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; builder.Append(&amp;quot;, Age = &amp;quot;); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; builder.Append(this.&amp;lt;Age&amp;gt;i__Field); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; builder.Append(&amp;quot; }&amp;quot;); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return builder.ToString(); &lt;br /&gt;} &lt;br /&gt; &lt;br /&gt;[DebuggerHidden] &lt;br /&gt;public override int GetHashCode() &lt;br /&gt;{ &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; int num = 0x5b485bf4; // Numero casuale &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; num = (-1521134295 * num) + EqualityComparer&amp;lt;&amp;lt;Language&amp;gt;j__TPar&amp;gt;.Default.GetHashCode(this.&amp;lt;Language&amp;gt;i__Field); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return ((-1521134295 * num) + EqualityComparer&amp;lt;&amp;lt;Age&amp;gt;j__TPar&amp;gt;.Default.GetHashCode(this.&amp;lt;Age&amp;gt;i__Field)); &lt;br /&gt;} &lt;br /&gt; &lt;br /&gt;[DebuggerHidden] &lt;br /&gt;public override bool Equals(object value) &lt;br /&gt;{ &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var type = value as &amp;lt;&amp;gt;f__AnonymousType0&amp;lt;&amp;lt;Language&amp;gt;j__TPar, &amp;lt;Age&amp;gt;j__TPar&amp;gt;; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return (((type != null) &amp;amp;&amp;amp; EqualityComparer&amp;lt;&amp;lt;Language&amp;gt;j__TPar&amp;gt;.Default.Equals(this.&amp;lt;Language&amp;gt;i__Field, type.&amp;lt;Language&amp;gt;i__Field)) &amp;amp;&amp;amp; EqualityComparer&amp;lt;&amp;lt;Age&amp;gt;j__TPar&amp;gt;.Default.Equals(this.&amp;lt;Age&amp;gt;i__Field, type.&amp;lt;Age&amp;gt;i__Field)); &lt;br /&gt;}&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Sono interessanti l'uso di &lt;strong&gt;DebuggerHidden&lt;/strong&gt; per evitare di far vedere dal debugger tali metodi e l'uso di &lt;strong&gt;EqualityComparer.Default&lt;/strong&gt; per ottenere l'hashcode o comparare i tipi primitivi utilizzati. EqualityComparer.Default restituisce un &lt;strong&gt;IEqualityComparer&amp;lt;T&amp;gt;&lt;/strong&gt; (fondamentale in LINQ) a seconda che il tipo implementi IEquatable&amp;lt;T&amp;gt;, sia nullabile o come ultima spiaggia, sovrascriva Equals e GetHashCode. Per comparare le stringhe (utile sempre in LINQ) abbiamo a disposizione la classe &lt;strong&gt;StringComparer&lt;/strong&gt; che permette diversi modi di comparazione delle stringhe: CurrentCulture, CurrentCultureIgnoreCase, InvariantCulture, InvariantCultureIgnoreCase, Ordinal, OrdinalIgnoreCase.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework/&quot; rel=&quot;tag&quot;&gt;.NET Framework&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.5/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.5&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/LINQ/&quot; rel=&quot;tag&quot;&gt;LINQ&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2197/Anonymous-Type-CSharp-3.0.aspx"/><issued>2008-01-04T14:21:18+01:00</issued><modified>2008-01-04T14:21:18+01:00</modified><slash:comments>0</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2197/Anonymous-Type-CSharp-3.0.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2197.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2197</trackback:ping></entry><entry><title>Habemus CardSpace!</title><id>http://blogs.aspitalia.com/ricciolo/post2198/Habemus-CardSpace.aspx</id><created>2008-01-03T14:51:00+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2198' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;E' un po' che io e &lt;a onclick=&quot;function anonymous()
{
function anonymous()
{
blankUrl(this.href); return false;
}
}&quot; href=&quot;http://blogs.aspitalia.com/daniele&quot;&gt;Daniele&lt;/a&gt; ci stiamo lavorando (circa due mesi), ma finalmente abbiamo implementato &lt;strong&gt;CardSpace&lt;/strong&gt; nella nostra community. Questo significa che da ora in poi potete fare login utilizzando le card self-issued. Una guida su come funziona l'ambaradam la trovate &lt;a onclick=&quot;function anonymous()
{
function anonymous()
{
blankUrl(this.href); return false;
}
}&quot; href=&quot;https://secure.aspitalia.com/profile/infocard.aspx&quot;&gt;qua&lt;/a&gt; e se avete gi&#224; a disposizione una card e non siente registratati, allora create un profilo &lt;a onclick=&quot;function anonymous()
{
function anonymous()
{
blankUrl(this.href); return false;
}
}&quot; href=&quot;https://secure.aspitalia.com/profile/policy.aspx&quot;&gt;qua&lt;/a&gt;, oppure associate la card ad un account pre esiste, dopo aver fatto il login, andando &lt;a onclick=&quot;function anonymous()
{
function anonymous()
{
blankUrl(this.href); return false;
}
}&quot; href=&quot;https://secure.aspitalia.com/profile/setcard.aspx&quot;&gt;qua&lt;/a&gt;. In generale la vostra card personale &#232; utilizzabile in tutti i portali dove compare questo logo standard:&lt;/p&gt;&lt;p&gt;&lt;img alt=&quot; &quot; hspace=&quot;0&quot; src=&quot;http://blogs.aspitalia.com/img/Ricciolo/CardSpace.png&quot; border=&quot;0&quot; /&gt; &lt;/p&gt;&lt;p&gt;Ovviamente la domanda &#232;: perch&#233; supportare l'identity metasystem?&lt;/p&gt;&lt;p&gt;Risposta:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;perch&#233; adeguarsi ad un sistema standard ed interoperabile ci permette di accogliere nuovi utenti molto pi&#249; facilmente. Basta selezionare la card utilizzata gi&#224; su altri portali e le informazioni sono gi&#224; disponibili; &lt;/li&gt;&lt;li&gt;perch&#233; non serve pi&#249; ricordarsi di password, utenti ed email; &lt;/li&gt;&lt;li&gt;perch&#233; un'unica interfaccia di selezione basata su comunicazioni sicure, &#232; sicuramente meglio dei mille sistemi inventati da ogni programmatore del mondo, abbattendo inoltre cos&#236;, fenomeni come phishing; &lt;/li&gt;&lt;li&gt;perch&#233; questo sistema di autenticazione &#232; utilizzabile anche al di fuori dal web: applicazioni windows, webservice ecc. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Non temete, implementare identity metasystem nei vostri portali &#232; facile e fattibile. L'unica difficolt&#224; &#232; il certificato per il canale SSL, ma dal .NET Framework 3.5 non &#232; pi&#249; obbligatorio se il nostro sito non &#232; una banca :-) La difficolt&#224; che abbiamo incontrato &#232; stata nel cercare di implementare un &lt;strong&gt;STS&lt;/strong&gt; (Security Token Server) per rilasciare delle nostre card marcate ASPItalia.com/WinFXItalia.com, da utilizzare nelle nostre community. Beh dunque, fare un STS non &#232; affatto semplice e il materiale a disposizione non &#232; completo. Parlando comunque con &lt;a onclick=&quot;function anonymous()
{
function anonymous()
{
blankUrl(this.href); return false;
}
}&quot; href=&quot;http://blogs.msdn.com/vbertocci/&quot;&gt;Vittorio Bertocci&lt;/a&gt;, che lavora in Microsoft e si sta dando parecchio da fare per diffondere l'adozione dell'identity metasystem, abbiamo maturato l'idea che fare da STS &#232; troppo per noi. STS che rilascia managed card deve essere un ente, una banca, uno stato. Per la nostra community bastano le semplici self-issued card. Maggiori dettagli tecnici sull'argomento li trovate &lt;a onclick=&quot;function anonymous()
{
function anonymous()
{
blankUrl(this.href); return false;
}
}&quot; href=&quot;http://www.winfxitalia.com/articoli/winfx/gestione-identita-digitali-windows-cardspace.aspx&quot;&gt;qua&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/ASPItalia.com/&quot; rel=&quot;tag&quot;&gt;ASPItalia.com&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2198/Habemus-CardSpace.aspx"/><issued>2008-01-03T14:51:00+01:00</issued><modified>2008-01-03T14:51:00+01:00</modified><slash:comments>4</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2198/Habemus-CardSpace.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2198.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2198</trackback:ping></entry><entry><title>WPF: attenzione ai template predefiniti</title><id>http://blogs.aspitalia.com/ricciolo/post2196/WPF-Attenzione-Template-Predefiniti.aspx</id><created>2008-01-02T13:48:16+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2196' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Certo, si pu&amp;#242; dormire lo stesso anche non sapendolo, ma sul nostro &lt;a href=&quot;http://forum.aspitalia.com/forum/29/.net-framework-3.0.aspx&quot; onclick=&quot;blankUrl(this.href); return false;&quot;&gt;forum&lt;/a&gt; &amp;#232; stata posta un'interessante domanda relativa ai Content di &lt;strong&gt;WPF&lt;/strong&gt;. Purtroppo la comodit&amp;#224; di certi elementi presenti ci fa ignorare il dietro le quinte e a volte ci porta a risultati inaspettati. E' il caso delle classi &lt;strong&gt;ContentControl&lt;/strong&gt; e &lt;strong&gt;HeaderedContentControl&lt;/strong&gt; che dispongono delle propriet&amp;#224; &lt;strong&gt;Header&lt;/strong&gt; e &lt;strong&gt;Content&lt;/strong&gt; di tipo Object e ci consentono di fare questo:&lt;/p&gt; &lt;p class=&quot;colorato&quot;&gt;&lt;code&gt;&amp;lt;Button&amp;gt;Ciao!&amp;lt;/Button&amp;gt;&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Innanzitutto tramite l'interfaccia IAddChild la stringa &amp;quot;Ciao!&amp;quot; viene impostata sulla propriet&amp;#224; Content ed equivale quindi a scrivere:&lt;/p&gt; &lt;p class=&quot;colorato&quot;&gt;&lt;code&gt;&amp;lt;Button&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Button.Content&amp;gt;Ciao!&amp;lt;/Button.Content&amp;gt; &lt;br /&gt;&amp;lt;/Button&amp;gt;&lt;/code&gt;&lt;/p&gt; &lt;p&gt;I vari skin applicati a Button o controlli simili, utilizzano l'oggetto &lt;strong&gt;ContentPresenter&lt;/strong&gt; per includere il contenuto nel layout. Quest'oggetto applica dei template predefiniti a seconda del tipo presente in Content:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Se &amp;#232; una stringa e &lt;strong&gt;RecognizesAccessKey&lt;/strong&gt; &amp;#232; a true, utilizza un template che crea un &lt;strong&gt;AccessText&lt;/strong&gt; e con Text valorizzato con il Content stesso; altrimenti utilizza un normale TextBlock con Text valorizzato con il Content stesso;&lt;/li&gt; &lt;li&gt;Se &amp;#232; un &lt;strong&gt;UIElement&lt;/strong&gt;, inserisce l'elemento stesso direttamente come figlio;&lt;/li&gt; &lt;li&gt;Se &amp;#232; un &lt;strong&gt;XmlNode&lt;/strong&gt;, utilizza un TextBlock con Binding XPath = &amp;quot;.&amp;quot;&lt;/li&gt; &lt;li&gt;Per gli altri restanti tipi, utilizza un TextBlock cercando di convertire prima con un &lt;strong&gt;TypeConverter&lt;/strong&gt; e poi con un ToString il tipo impostato come Content.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Detto questo, quali possono essere i risultati inattesi? Prendiamo questo esempio:&lt;/p&gt; &lt;p class=&quot;colorato&quot;&gt;&lt;code&gt;&amp;lt;Menu&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;MenuItem Header=&amp;quot;_One&amp;quot; /&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;MenuItem Header=&amp;quot;_Two&amp;quot; /&amp;gt; &lt;br /&gt;&amp;lt;/MenuItem&amp;gt;&lt;/code&gt;&lt;/p&gt; &lt;p&gt;L'uso degli underscore &amp;#232; riconosciuto da AccessText (il ContentPresenter del MenuItem ha RecognizesAccessKey a true) e permette l'utilizzo dello shorcut effettuando la sottolineatura della lettera che lo segue. Se usiamo per&amp;#242; il Binding XML, per esempio, gli underscore non vengono pi&amp;#249; rinosciuti:&lt;/p&gt; &lt;p class=&quot;colorato&quot;&gt;&lt;code&gt;&amp;lt;MenuItem Header=&amp;quot;{Binding XPath=/item/@text}&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Questo perch&amp;#233; non viene pi&amp;#249; usato il template predefinito riservato alle stringhe. Per ovviare a questo problema, occorre creare in modo esplicito l'oggetto AccessText:&lt;/p&gt; &lt;p class=&quot;colorato&quot;&gt;&lt;code&gt;&amp;lt;MenuItem&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;MenuItem.Header&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;AccessText Text=&amp;quot;{Binding XPath=/item/@text}&amp;quot; /&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/MenuItem.Header&amp;gt; &lt;br /&gt;&amp;lt;/MenuItem&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2196/WPF-Attenzione-Template-Predefiniti.aspx"/><issued>2008-01-02T13:48:16+01:00</issued><modified>2008-01-02T13:48:16+01:00</modified><slash:comments>0</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2196/WPF-Attenzione-Template-Predefiniti.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2196.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2196</trackback:ping></entry><entry><title>Curiosit&amp;#224; sui Thread</title><id>http://blogs.aspitalia.com/ricciolo/post2187/Curiosita-Thread.aspx</id><created>2007-12-16T23:45:00+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2187' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;In questi giorni grazie ad un esigenza di &lt;a onclick=&quot;function anonymous()
{
function anonymous()
{
function anonymous()
{
blankUrl(this.href); return false;
}
}
}&quot; href=&quot;http://blogs.devleap.com/rob/&quot;&gt;Rob&lt;/a&gt; e &lt;a onclick=&quot;function anonymous()
{
function anonymous()
{
function anonymous()
{
blankUrl(this.href); return false;
}
}
}&quot; href=&quot;http://blogs.devleap.com/paolo/&quot;&gt;Paolo&lt;/a&gt;, ho voluto approfondire un aspetto di cui ero gi&#224; a conoscienza, ma del quale non avevo mai fatto test. &lt;br /&gt;Come sapete, un campo dichiarato in una classe pu&#242; teoricamente subire contemporaneamente l'accesso da pi&#249; &lt;strong&gt;thread&lt;/strong&gt; e spesso per rendere la classe thread-safe si ricorrono a tecniche di sincronizzazione per evitare che pi&#249; thread cambino contemporanemante il campo. Non &#232; detto infatti che una singola istruzione di assegnazione sia una singola istruzione di CPU e questo pu&#242; portare ad inaspettati risultati. Questo problema si fa inoltre pi&#249; frequente se si dichiara static (o shared in VB) il campo, condividendo il valore del membro per l'intero AppDomain.&lt;/p&gt;&lt;p&gt;A volte per&#242;, si vuole rendere l'istanza del campo accessible da chiunque purch&#233; dal medesimo thread, togliendo quindi il problema dell'accesso concorrente. L'attributo &lt;strong&gt;ThreadStatic&lt;/strong&gt; permette di marcare un campo e di avere questo comportamento:&lt;/p&gt;&lt;p&gt;&lt;code&gt;[ThreadStatic] &lt;br /&gt;private static object threadState;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Questa tecnica viene sfruttata per esempio dall'oggetto &lt;strong&gt;Transaction&lt;/strong&gt; (System.Transactions) per mantenere l'oggetto rappresentante la transazione corrente cosicch&#232; qualsiasi sotto chiamata possa accedere alla transazione corrente semplicemente chiamando Transaction.Current, il tutto isolato per thread (la transazione infatti non &#232; visibile in altri thread, ma ne viene creata un'altra). Lo stesso comportamento, seppure meno comodo, si pu&#242; ottenere usando &lt;strong&gt;Thread.AllocateNamedDataSlot&lt;/strong&gt;, Thread.SetData e Thread.GetData che permettono di allocare per nome uno spazio, di impostarlo e di leggerlo, dove inserire un riferimento ad un oggetto.&lt;/p&gt;&lt;p&gt;La problematica di questo approccio &#232; che nel caso in cui da un thread ne avviamo un altro e si vuole portare con se questi valori &amp;quot;speciali&amp;quot;, occorre passarseli tramite argomenti o classi d'appoggio per poi essere copiati sul nuovo thread. Inoltre nel caso del &lt;strong&gt;ThreadPool&lt;/strong&gt;, quell'insieme di thread gi&#224; pronti all'uso, utilizzati quando si chiama la Begin*** di un delegate o si usa &lt;strong&gt;ThreadPool.QueueUserWorkItem&lt;/strong&gt;, il campo statico risulta visibile alle operazioni che verranno prese in carico dal medesimo thread e mai rilasciato (si pensi al Dispose dell'oggetto) se non sovrascritto o impostato a null (il ThreadPool nel .NET 2.0 &#232; composta da 25 Thread per CPU e di 500 IO Thread per CPU, in ASP.NET 2.0 sono 100/100, nel.NET 3.5 sono diventanti 250/500, mentre in ASP.NET 3.5 nella modalit&#224; AutoConfig sono rimasti invariati).&lt;/p&gt;&lt;p&gt;Per risolvere questo problema viene in aiuto la classe &lt;strong&gt;CallContext&lt;/strong&gt; (System.Runtime.Remoting.Messaging) con i metodi &lt;strong&gt;LogicalGetData&lt;/strong&gt; e &lt;strong&gt;LogicalSetData&lt;/strong&gt; per leggere e impostare in base ad una chiave il riferimento ad un oggetto. Il comportamento &#232; simile a ThreadStatic, ma questi valori sono relativi al contesto in cui sono stati impostati. Per capire meglio ho creato questa classe:&lt;/p&gt;&lt;p&gt;&lt;code&gt;public class MyObject : Component &lt;br /&gt;{ &lt;br /&gt;private readonly string _name; &lt;/p&gt;&lt;p&gt;public MyObject(string name) &lt;br /&gt;{ &lt;br /&gt;&#160;&#160;&#160; _name = name; &lt;br /&gt;} &lt;/p&gt;&lt;p&gt;protected override void Dispose(bool disposing) &lt;br /&gt;{&#160;&lt;br /&gt;&#160;&#160;&#160; base.Dispose(disposing); &lt;/p&gt;&lt;p&gt;&#160;&#160;&#160; Console.WriteLine(&amp;quot;Disposed {0}&amp;quot;, _name); &lt;br /&gt;} &lt;/p&gt;&lt;p&gt;public override string ToString() &lt;br /&gt;{&#160;&lt;br /&gt;&#160;&#160;&#160; return _name; &lt;br /&gt;} &lt;br /&gt;}&lt;/code&gt;&lt;/p&gt;&lt;p&gt;E' una semplice classe che implementa &lt;strong&gt;IDisposable&lt;/strong&gt; cos&#236; da sapere quando l'oggetto, identificato con un nome, viene distrutto. Poi ho creato una ConsoleApplication che esegue su un thread del pool il controllo di un campo marcato con ThreadStatic, lo valorizza se &#232; nullo e ne stampa il valore. La stessa operazione viene effettuata usando CallContext. Inoltre, attendo la fine dell'esecuzione per assicurarmi che le altre successive operazioni vengono effettuate nuovamente sul medesimo thread ed utilizzo &lt;strong&gt;GC.Collect&lt;/strong&gt; per assicurarmi che gli oggetti, non pi&#249; in uso, vengano distrutti (mi raccomando, in vere applicazioni non si deve chiamare se non in rare eccezioni):&lt;/p&gt;&lt;p /&gt;&lt;p&gt;&lt;code&gt;class Program &lt;br /&gt;{ &lt;/p&gt;&lt;p&gt;[ThreadStatic] &lt;br /&gt;private static object threadState; &lt;/p&gt;&lt;p&gt;static void Main(string[] args) &lt;br /&gt;{&#160;&lt;br /&gt;&#160;&#160;&#160; // Metodo da invocare su un Thread del pool&#160;&lt;br /&gt;&#160;&#160;&#160; WaitCallback wc = DoWork; &lt;/p&gt;&lt;p&gt;&#160;&#160;&#160; for (int x = 0; x &amp;lt; 3; x++)&#160;&lt;br /&gt;&#160;&#160;&#160; {&#160;&lt;br /&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160; // Invoco e attendo che finisca&#160;&lt;br /&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160; wc.BeginInvoke(null, EndWork, wc).AsyncWaitHandle.WaitOne(); &lt;/p&gt;&lt;p&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160; // Forzo la liberazione degli oggetti&#160;&lt;br /&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160; GC.Collect();&#160;&lt;br /&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160; GC.WaitForPendingFinalizers();&#160;&lt;br /&gt;&#160;&#160;&#160; } &lt;/p&gt;&lt;p&gt;&#160;&#160;&#160; // Avvio l'operazione su un nuovo Thread&#160;&lt;br /&gt;&#160;&#160;&#160; Thread t = new Thread(DoWork);&#160;&lt;br /&gt;&#160;&#160;&#160; t.Start();&#160;&lt;br /&gt;&#160;&#160;&#160; t.Join(); &lt;/p&gt;&lt;p&gt;&#160;&#160;&#160; // Forzo la liberazione degli oggetti&#160;&lt;br /&gt;&#160;&#160;&#160; GC.Collect();&#160;&lt;br /&gt;&#160;&#160;&#160; GC.WaitForPendingFinalizers(); &lt;/p&gt;&lt;p&gt;&#160;&#160;&#160; Console.Read(); &lt;br /&gt;} &lt;/p&gt;&lt;p&gt;private static void EndWork(IAsyncResult ar) &lt;br /&gt;{&#160;&lt;br /&gt;&#160;&#160;&#160; ((WaitCallback)ar.AsyncState).EndInvoke(ar); &lt;br /&gt;} &lt;/p&gt;&lt;p&gt;const string DataKey = &amp;quot;test&amp;quot;; &lt;/p&gt;&lt;p&gt;static void DoWork(object state) &lt;br /&gt;{&#160;&lt;br /&gt;&#160;&#160;&#160; Console.WriteLine(&amp;quot;-----------------&amp;quot;);&#160;&lt;br /&gt;&#160;&#160;&#160; Console.WriteLine(&amp;quot;Thread {0}&amp;quot;, Thread.CurrentThread.ManagedThreadId); &lt;/p&gt;&lt;p&gt;&#160;&#160;&#160; object t = CallContext.LogicalGetData(DataKey);&#160;&lt;br /&gt;&#160;&#160;&#160; if (t == null)&#160;&lt;br /&gt;&#160;&#160;&#160; {&#160;&lt;br /&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160; t = new MyObject(&amp;quot;LogicalData&amp;quot;);&#160;&lt;br /&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.WriteLine(&amp;quot;LogicalData set&amp;quot;);&#160;&lt;br /&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160; CallContext.LogicalSetData(DataKey, t);&#160;&lt;br /&gt;&#160;&#160;&#160; }&#160;&lt;br /&gt;&#160;&#160;&#160; else&#160;&lt;br /&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.WriteLine(&amp;quot;LogicalData: {0}&amp;quot;, t); &lt;/p&gt;&lt;p&gt;&#160;&#160;&#160; t = threadState;&#160;&lt;br /&gt;&#160;&#160;&#160; if (t == null)&#160;&lt;br /&gt;&#160;&#160;&#160; {&#160;&lt;br /&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160; t = new MyObject(&amp;quot;DataThread&amp;quot;);&#160;&lt;br /&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160; threadState = t;&#160;&lt;br /&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.WriteLine(&amp;quot;DataThread set&amp;quot;);&#160;&lt;br /&gt;&#160;&#160;&#160; }&#160;&lt;br /&gt;&#160;&#160;&#160; else&#160;&lt;br /&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.WriteLine(&amp;quot;DataThread: {0}&amp;quot;, t);&#160;&lt;br /&gt;&#160;&#160;&#160; } &lt;br /&gt;}&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Se lo si esegue, il risultato &#232; il seguente:&lt;/p&gt;&lt;p&gt;&lt;code&gt;----------------- &lt;br /&gt;Thread 6 &lt;br /&gt;LogicalData set &lt;br /&gt;DataThread set &lt;br /&gt;----------------- &lt;br /&gt;Thread 6 &lt;br /&gt;LogicalData set &lt;br /&gt;DataThread: DataThread &lt;br /&gt;Disposed LogicalData &lt;br /&gt;----------------- &lt;br /&gt;Thread 6 &lt;br /&gt;LogicalData set &lt;br /&gt;DataThread: DataThread &lt;br /&gt;Disposed LogicalData &lt;br /&gt;Disposed LogicalData &lt;br /&gt;----------------- &lt;br /&gt;Thread 11 &lt;br /&gt;LogicalData set &lt;br /&gt;DataThread set &lt;br /&gt;Disposed DataThread&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Come si vede, alla prima esecuzione di DoWork, entrambi i modi di memorizzare MyObject impostano il valore. Alla seconda esecuzione CallContext &#232; di nuovo vuoto e va rivalorizzato, mentre threadState contiene il valore impostato sulla prima esecuzione. Lo stesso avviene anche alla terza esecuzione. E' interessante notare che l'oggetto impostato con CallContext viene effettivamente rilasciato e quindi ucciso dal GC solo all'avviarsi della nuova operazione sul medesimo thread (infatti il primo GC.Collect non ha sortito nessun effetto). Poich&#233; i thread del pool non muoiono mai, DataThread non viene mai eliminato, ad eccezione di quello impostato nel Thread creato manualmente (l'esecuzione &#232; finita e quindi il thread &#232; inutilizzabile). &lt;br /&gt;Tutto questo meccanismo &#232; gestito dalla classe &lt;strong&gt;ExecutionContext&lt;/strong&gt; (System.Threading) che &#232; in grado di catturare, mettere a disposizione o di togliere il contesto e tutti valori ad esso associati. Quando si chiama ThreadPool.QueueUserWorkItem o il Begin*** di un metodo, viene chiamato ExecutionContext.Capture per catturare il contesto e tenerselo pronto quando il thread prende in consegna il delegate da eseguire, ripristinando quindi il contesto chiamando il metodo Run. Se avete mai dovuto creare un vostro ThreadPool, tipo &lt;a onclick=&quot;function anonymous()
{
function anonymous()
{
function anonymous()
{
blankUrl(this.href); return false;
}
}
}&quot; href=&quot;http://msdn.microsoft.com/msdnmag/issues/06/03/netmatters/&quot;&gt;questo&lt;/a&gt;, avrete sicuramente avuto a che fare con questa classe. Il bello di questo meccanismo &#232; che se usiamo CallContext per mantenere dei valori ed invochiamo delegate asincroni o creiamo thread, automaticamente il contesto viene passato sull'altro thread condividendolo per la durata dell'operazione. Se nell'esempio precedente quindi si imposta prima di qualsiasi accodamento, l'istruzione CallContext.LogicalSetData(DataKey, new MyObject(&amp;quot;test&amp;quot;)); si ottiene a console:&lt;/p&gt;&lt;p /&gt;&lt;p&gt;&lt;code&gt;Thread 6 &lt;br /&gt;LogicalData: test &lt;br /&gt;DataThread set &lt;br /&gt;----------------- &lt;br /&gt;Thread 6 &lt;br /&gt;LogicalData: test &lt;br /&gt;DataThread: DataThread &lt;br /&gt;----------------- &lt;br /&gt;Thread 6 &lt;br /&gt;LogicalData: test &lt;br /&gt;DataThread: DataThread &lt;br /&gt;----------------- &lt;br /&gt;Thread 11 &lt;br /&gt;LogicalData: test &lt;br /&gt;DataThread set &lt;br /&gt;Disposed DataThread&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Si noti che LogicalData su tutti i thread &#232; gi&#224; impostato.&lt;/p&gt;&lt;p&gt;Un'ultimo aspetto riguarda ASP.NET che utilizza anch'esso CallContext.HostContext ogni qualvolta si interroga HttpContext.Current, ma se si usano pagine asincrone con task ecc, i metodi asincroni non dispongono del contesto web e HttpContext.Current ritorna null. Diversamente usando CallContext.LogicalSetData si ha a disposizione l'oggetto anche sui task asincroni ed &#232; quindi l'ideale se dovete mantenere DataContext (LINQ) o Session (NHibernate).&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2187/Curiosita-Thread.aspx"/><issued>2007-12-16T23:45:00+01:00</issued><modified>2007-12-16T23:45:00+01:00</modified><slash:comments>4</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2187/Curiosita-Thread.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2187.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2187</trackback:ping></entry><entry><title>Perch&amp;#233; non usate lo statement using?</title><id>http://blogs.aspitalia.com/ricciolo/post2177/Usate-Statement-Using.aspx</id><created>2007-12-06T12:38:32+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2177' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Me lo chiedo perch&amp;#233; la vedo raramente usata nei forum e nel codice che mi capita di guardare e mi domando il perch&amp;#233;, visto che &amp;#232; cos&amp;#236; comoda da usare. Beh il mio consiglio &amp;#232;: qualsiasi oggetto create, se implementa &lt;strong&gt;IDisposable&lt;/strong&gt;, usate sempre la using. &lt;br /&gt;Per i seguenti motivi:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Occorre sempre chiudere risorse unmanaged in modo esplicito e il prima possibile. Se si demanda il lavoro al &lt;strong&gt;Garbage Collector&lt;/strong&gt; il Dispose verr&amp;#224; effettuato sfruttando la &lt;strong&gt;Finalize&lt;/strong&gt; e l'oggetto rester&amp;#224; nell'heap per un giro di GC in pi&amp;#249; e rischiamo inoltre che l'oggetto diventi pi&amp;#249; forte come generation e non venga pi&amp;#249; rimosso; &lt;/li&gt; &lt;li&gt;Anche se l'oggetto non fa uso risorse unmanaged, la Dispose va chiamata lo stesso. Primo perch&amp;#233; non possiamo mai sapere se in una futura versione l'oggetto utilizzer&amp;#224; tali risorse e secondo perch&amp;#233; chiamando Dispose, se la classe &amp;#232; scritta bene, viene chiamato &lt;strong&gt;GC.SuppressFinalize&lt;/strong&gt;(this) cos&amp;#236; da togliere l'oggetto dalla finalization list, il GC lo rimuover&amp;#224; dall'heap e il problema indicato nel primo punto non si verificher&amp;#224;. &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Se scriviamo delle nostre classi che fanno uso di risorse unmanaged o di classi che a loro volta ne fanno uso, vi consiglio di ereditare da &lt;strong&gt;System.ComponentModel.Component&lt;/strong&gt;. Implementa gi&amp;#224; il pattern Dispose, con l'interfaccia IDisposable, il metodo Finalize e mettendo a disposizione un metodo virtuale Dispose(bool disposing). Una tipica classe &amp;#232; cos&amp;#236;:&lt;/p&gt; &lt;code&gt;public class MiaClasse : System.ComponentModel.Component &lt;br /&gt;{ &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; private bool disposed; &lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public void MioMetodo() &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; { &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (disposed) &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; throw new ObjectDisposedException(base.GetType().Name); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; protected override void Dispose(bool disposing) &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; { &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (disposing) { &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; risorsaunmanaged.Dispose(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; risorsaunmanaged = null; &lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; this.disposed = true; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; base.Dispose(disposing); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;br /&gt;}&lt;/code&gt; &lt;p&gt;L'uso della variabile disposed &amp;#232; &amp;quot;facoltaltiva&amp;quot;, ma utile se vogliamo lanciare un eccezione nel caso qualcuno chiami un nostro metodo quando ne ha gi&amp;#224; chiamato il Dispose. &lt;br /&gt;Quindi insomma, usiamo la using che non vi costa e scriviamo le classi nel modo giusto ;-)&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework/&quot; rel=&quot;tag&quot;&gt;.NET Framework&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2177/Usate-Statement-Using.aspx"/><issued>2007-12-06T12:38:32+01:00</issued><modified>2007-12-06T12:38:32+01:00</modified><slash:comments>15</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2177/Usate-Statement-Using.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2177.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2177</trackback:ping></entry><entry><title>Spettro audio con WPF</title><id>http://blogs.aspitalia.com/ricciolo/post2168/Spettro-Audio-WPF.aspx</id><created>2007-11-29T00:28:00+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2168' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Avete presente quei siti web che permettono di ascoltare tracce audio? E quelle barre che vanno su e gi&#249; senza senso anche se non si sente niente? Ecco, capisco che un player come quello di Flash o Silverlight possa non implementare l'analisi dell'audio, ma questa tecnica l'ho vista applicata anche in applicazioni client, anche scritte in WPF.&lt;/p&gt;&lt;p&gt;Mi &#232; venuta quindi voglia di provare ad implementare una visualizzazione a barre dell'audio che si ascolta e di conseguenza ho cominciato dall'inizio: dalla teoria. Prima di tutto bisogna sapere che nel digitale le tracce audio sono campionate, un po' come i frame nei video, tantissime volte al secondo. Questi sample per esempio, a qualit&#224; CD sono 44100 al secondo e occupano 16bit per ogni canale e ovviamente pi&#249; &#232; alto il sample, maggiore &#232; la qualit&#224;. Questa serie di byte si possono considerare come tante di sinusoidi, ciascuna delle quali possiede una frequenza e un'ampiezza. Queste informazioni si possono ottenere applicando un algoritmo di nome Fast Fourier Transform (FFT) e sfruttarle per creare spettri audio. Non sono un comuque un esperto ne di matematica ne di audio, quindi se siete interessati vi rimando a &lt;a onclick=&quot;function anonymous()
{
function anonymous()
{
blankUrl(this.href); return false;
}
}&quot; href=&quot;http://www.relisoft.com/science/physics/sound.html&quot;&gt;questa&lt;/a&gt; buona guida.&lt;/p&gt;&lt;p&gt;A questo punto mi serviva un modo per caricare i byte delle tracce audio e un sistema veloce per applicare FFT. In giro si trovano esempi che usano le API waveIn*** e waveOut***, ma sono limitati ai file wav che contengono solamente campionature pure. Ho deciso quindi di usare &lt;strong&gt;DirectShow&lt;/strong&gt; che, sebbene sia pi&#249; complesso, &#232; potentissimo, ci sono filtri di ogni genere e tramite un SampleGrabber posso intercettare i sample in uscita dopo che sono stati decodificati. Questo mi permette quindi di aprire qualsiasi file audio compatibile con DirectShow. Considerando che FFT pu&#242; essere applicato solo ad un set che sia una potenza di 2, che pi&#249; sample prendo e pi&#249; &#232; preciso, ma che ad ogni secondo devo garantire una certa fluidit&#224; delle barre, ho deciso di campionare 4096 sample al secondo, cos&#236; da garantire circa 11 frame al secondo.&lt;/p&gt;&lt;p&gt;Ovviamente, visto che ve ne ho parlato qualche &lt;a onclick=&quot;function anonymous()
{
function anonymous()
{
blankUrl(this.href); return false;
}
}&quot; href=&quot;http://blogs.aspitalia.com/ricciolo/post2167/interoperabilita-.net-c-cli.aspx&quot;&gt;giorno fa&lt;/a&gt;, ho usato &lt;strong&gt;C++ CLI&lt;/strong&gt; per creare una DLL mixed dove una classe managed utilizza una unmanaged la quale crea il grafo DirectShow, prepara i filtri ed esegue l'analisi dell'audio, limitando quindi al minimo l'interop e ottenendo il massimo delle prestazioni. Ogni sample ottenuto viene raggruppato per range di frequenza e memorizzato il picco. Ho creato poi un element &lt;strong&gt;AudioVisualization&lt;/strong&gt; in WPF che ad intervalli regolari interroga i picchi e tramite animation mostra le barre. Il risultato &#232; buono e il rendering basato su WPF permette di realizzare qualsiasi tipo di visualizzazione.&lt;/p&gt;&lt;p&gt;Ho creato inoltre un'applicazione demo dallo skin molto semplice; purtroppo il &lt;a onclick=&quot;function anonymous()
{
function anonymous()
{
blankUrl(this.href); return false;
}
}&quot; href=&quot;http://blogs.aspitalia.com/nostromo/&quot;&gt;mio grafico&lt;/a&gt; di fiducia ultimamente &#232; molto occupato (a giocare :-D). Ecco un video dimostrativo:&lt;/p&gt;&lt;embed pluginspage=&quot;http://macromedia.com/go/getflashplayer&quot; src=&quot;http://images.video.msn.com/flash/soapbox1_1.swf&quot; width=&quot;432&quot; height=&quot;364&quot; type=&quot;application/x-shockwave-flash&quot; flashvars=&quot;c=v&amp;amp;v=66f292d3-3230-44de-ba6a-53a053513b94&amp;amp;ifs=true&amp;amp;fr=msnvideo&amp;amp;mkt=it-IT&amp;amp;brand=&quot; allowfullscreen=&quot;true&quot; base=&quot;http://images.video.msn.com&quot; quality=&quot;high&quot; /&gt;&lt;/embed /&gt;&lt;br /&gt;&lt;a title=&quot;Reyalp&quot; href=&quot;http://video.msn.com/video.aspx?vid=66f292d3-3230-44de-ba6a-53a053513b94&quot; target=&quot;_new&quot;&gt;Video: Reyalp&lt;/a&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/Silverlight/&quot; rel=&quot;tag&quot;&gt;Silverlight&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/XAML/&quot; rel=&quot;tag&quot;&gt;XAML&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2168/Spettro-Audio-WPF.aspx"/><issued>2007-11-29T00:28:00+01:00</issued><modified>2007-11-29T00:28:00+01:00</modified><slash:comments>4</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2168/Spettro-Audio-WPF.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2168.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2168</trackback:ping></entry><entry><title>Interoperabilit&amp;#224; .NET con C++ CLI</title><id>http://blogs.aspitalia.com/ricciolo/post2167/Interoperabilita-.NET-C-CLI.aspx</id><created>2007-11-26T23:26:00+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2167' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;In quest'ultimo periodo mi sono addentrato in un mondo che ho sempre ammirato, ma che non ho mai avuto il coraggio di provare: il &lt;strong&gt;C++ CLI&lt;/strong&gt;. Ammirato perch&#233; gi&#224; non ho mai usato C++, figuriamoci un linguaggio pi&#249; evoluto. Per chi non lo sapesse, infatti, C++ CLI &#232; un linguaggio standard ECMA evoluzione delle Managed Extensions C++ e quindi di C++ che permette di mettere in comunicazione il mondo managed .NET con quello unmanaged.&lt;/p&gt;&lt;p&gt;Questo vuol dire che &#232; possibile scrivere DLL che contengano sia codice nativo che lavori con qualsiasi API, sia codice managed che faccia uso poi di classi native. Oltre a ci&#242; &#232; possibile ottenere&#160;il codice di interop in automatico&#160;scrivendo direttamente da&#160;codice managed chiamate a tipi o funzioni native. Cos&#236; facendo si riduce al minimo il marshaling dei tipi e C++ CLI diventa l'ideale per scrivere classi che&#160; permettano di beneficiare dei pregi dei due mondi.&lt;br /&gt;Se avete avuto modo di usare la classe &lt;strong&gt;Marshal&lt;/strong&gt; di System.Runtime.InteropServices sapete delle fatiche che si devono compiere per le strutture ecc e apprezzerete sicuramente questo nuovo strumento.&lt;/p&gt;&lt;p&gt;Beh insomma dopo un po' che ci sto lavorando devo dire che &#232; ganzissimo. Ti senti come &lt;a href=&quot;http://it.wikipedia.org/wiki/Peter_Petrelli&quot;&gt;Peter Petrelli&lt;/a&gt; quando si ritrova tutti quei poteri. Come il personaggio nel senso che come lui non sono capace di usarli e mi fermo fra elementari ostacoli come conversione dei tipi, utilizzo delle librerie e puntatori. Pian piano per&#242; sto prendendo possesso di questi poteri, quindi pi&#249; avanti vi illustrer&#242; cosa sono riuscito a fare.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework/&quot; rel=&quot;tag&quot;&gt;.NET Framework&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_2.0/&quot; rel=&quot;tag&quot;&gt;.NET Framework 2.0&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.0/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.0&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.5/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.5&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2167/Interoperabilita-.NET-C-CLI.aspx"/><issued>2007-11-26T23:26:00+01:00</issued><modified>2007-11-26T23:26:00+01:00</modified><slash:comments>1</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2167/Interoperabilita-.NET-C-CLI.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2167.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2167</trackback:ping></entry><entry><title>Controllo WPF: AdvancedListBox</title><id>http://blogs.aspitalia.com/ricciolo/post2154/Controllo-WPF-AdvancedListBox.aspx</id><created>2007-10-24T19:24:00+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2154' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Colto da un momento di creativit&#224; o meglio, rubando l'idea a Zune2, ho voluto creare una ListBox che avesse un effetto transitorio nella selezione. In pratica invece di avere il background del &lt;strong&gt;Border&lt;/strong&gt; colorato e basta, avvio un'animazione che porta alla colorazione totale del Border. Nello stesso tempo decoloro l'elemento precedentemente colorato.&lt;/p&gt;&lt;p&gt;Per farlo ho dovuto estendere la ListBox e la ListBoxItem per avere tre nuove propriet&#224; che mi dicono se l'elemento sta per essere selezionato, se sta per essere deselezionato e qual'&#232; la direzione di navigazione.&lt;/p&gt;&lt;p&gt;Ecco il risultato. Ovviamente non &#232; l'unico effetto che si pu&#242; fare.&lt;/p&gt;&lt;p&gt;&lt;embed pluginspage=&quot;http://macromedia.com/go/getflashplayer&quot; src=&quot;http://images.video.msn.com/flash/soapbox1_1.swf&quot; width=&quot;432&quot; height=&quot;364&quot; type=&quot;application/x-shockwave-flash&quot; quality=&quot;high&quot; base=&quot;http://images.video.msn.com&quot; allowfullscreen=&quot;true&quot; flashvars=&quot;c=v&amp;amp;v=13eb4c7c-abd2-441f-a86c-e3ded1ee22e2&amp;amp;ifs=true&amp;amp;fr=msnvideo&amp;amp;mkt=it-IT&amp;amp;brand=&quot; /&gt;&lt;/embed /&gt;&lt;br /&gt;&lt;a title=&quot;WPF AdvancedListBox&quot; href=&quot;http://video.msn.com/video.aspx?vid=13eb4c7c-abd2-441f-a86c-e3ded1ee22e2&quot; target=&quot;_new&quot;&gt;Video: WPF AdvancedListBox&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Sorgenti e applicazioni di test &lt;a href=&quot;http://lab.ricciolo.aspitalia.com/downloads/Ricciolo.controls.advancedlistbox.zip?lab=52&quot;&gt;qui&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework/&quot; rel=&quot;tag&quot;&gt;.NET Framework&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.0/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.0&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.5/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.5&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/Windows_Presentation_Foundation/&quot; rel=&quot;tag&quot;&gt;Windows Presentation Foundation&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/XAML/&quot; rel=&quot;tag&quot;&gt;XAML&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2154/Controllo-WPF-AdvancedListBox.aspx"/><issued>2007-10-24T19:24:00+01:00</issued><modified>2007-10-24T19:24:00+01:00</modified><slash:comments>0</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2154/Controllo-WPF-AdvancedListBox.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2154.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2154</trackback:ping></entry><entry><title>Multithreading WPF nel Binding</title><id>http://blogs.aspitalia.com/ricciolo/post2153/Multithreading-WPF-Binding.aspx</id><created>2007-10-21T23:40:00+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2153' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Devo segnalarvi&#160;un errore nello &lt;a href=&quot;http://www.winfxitalia.com/liste/usag/script.aspx?ID=17&quot;&gt;script #17&lt;/a&gt; dove spiego come implementare &lt;strong&gt;INotifyPropertyChanged&lt;/strong&gt;. Di sbagliato c'&#232; la frase in cui dicevo che &#232; obbligatorio invocare l'evento&#160;tramite il&#160;&lt;strong&gt;Dispatcher&lt;/strong&gt;, quindi sul thread principale, e mostravo come chiamare la BeginInvoke.&lt;/p&gt;&lt;p&gt;In realt&#224; il motore di Binding sull'evento PropertyChanged internamente controlla gi&#224; se il thread corrente &#232; quello principale. In caso contrario accoda l'evento sul Dispatcher con priorit&#224; DataBind. Quindi quello che proponevo non era sbagliato, ma inutile, risparmiando solo del lavoro al motore di Binding.&lt;/p&gt;&lt;p&gt;C'&#232; da dire comunque che non &#232; dato sapere chi utilizza le nostre propriet&#224;, ma non &#232; altrettanto bello mettere della logica specifica di WPF nelle classi (infatti non lo proponevo per il Domain Model). Va comunque fatta attenzione che solo l'oggetto Binding gestisce questo aspetto. Per esempio le &lt;strong&gt;CollectionView&lt;/strong&gt; che lavorano sulle collezioni, s'arrabbiano generando un'eccezione&#160;se modichiamo le liste da altri thread. Possiamo per&#242; aggirare il problema invocando PropertyChanged e CollectionChanged sul thread principale affidandoci al Dispatcher. Se usate &lt;strong&gt;ObservableCollection&amp;lt;T&amp;gt;,&lt;/strong&gt; vi basta sovrascrivere OnPropertyChanged e OnCollectionChanged.&lt;/p&gt;&lt;p&gt;Mi scuso per la mala informazione...&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework/&quot; rel=&quot;tag&quot;&gt;.NET Framework&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.0/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.0&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.5/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.5&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/Windows_Presentation_Foundation/&quot; rel=&quot;tag&quot;&gt;Windows Presentation Foundation&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2153/Multithreading-WPF-Binding.aspx"/><issued>2007-10-21T23:40:00+01:00</issued><modified>2007-10-21T23:40:00+01:00</modified><slash:comments>0</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2153/Multithreading-WPF-Binding.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2153.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2153</trackback:ping></entry></feed>