Stamane, girovagando all'interno del framework come mi capita spesso, in compagnia del fido Reflector, mi sono imbattuto in un paio di classi che non sapevo facessero parte di Silverlight 2.0. Di AsyncOperationManager e AsyncOperation avevo già letto, ma non avevo mai pensato di poterle sfruttare nel plugin per sincronizzare un thread di download e la user interface. Un rapido refactoring mi ha infine confermato che la tecnica funziona e anche bene consentendo il grande vantaggio di non doversi portare in giro un riferimento al Dispatcher o al SynchronizationContext.

Ecco un breve esempio di come usare AsyncOperationManager; Poniamo di dover scaricare un file dalla rete, facendo uso di HttpWebRequest. L'uso di BeginGetResponse() implica una chiamata asincrona e al rientro per notificare l'interfaccia, ad esempio sollevando un evento, saremmo costretti all'operazione di sincronizzazione:

   1: public class DownloadManager
   2: {
   3:     /// <summary>
   4:     /// Enqueues the download.
   5:     /// </summary>
   6:     /// <param name="uri">The URI.</param>
   7:     public void DownloadFile(Uri uri)
   8:     {
   9:         DownloadState state = new DownloadState
  10:         {
  11:             Operation = AsyncOperationManager.CreateOperation(null),
  12:             Request = (HttpWebRequest)WebRequest.Create(uri)
  13:         };
  14:  
  15:         state.Request.Method = "GET";
  16:         state.Request.BeginGetResponse(new AsyncCallback(Download_Completed), state);
  17:     }
  18:  
  19:     /// <summary>
  20:     /// Download_s the completed.
  21:     /// </summary>
  22:     /// <param name="result">The result.</param>
  23:     private void Download_Completed(IAsyncResult result)
  24:     {
  25:         DownloadState state = result.AsyncState as DownloadState;
  26:  
  27:         if (state != null)
  28:         {
  29:             try
  30:             {
  31:                 HttpWebResponse response = (HttpWebResponse)state.Request.EndGetResponse(result);
  32:  
  33:                 if (response.StatusCode == HttpStatusCode.OK)
  34:                     state.Operation.PostOperationCompleted(
  35:                         new SendOrPostCallback(OnDownloadCompleted), response);
  36:                 else if (response.StatusCode == HttpStatusCode.NotFound)
  37:                     state.Operation.PostOperationCompleted(
  38:                         new SendOrPostCallback(OnDownloadFailed), new InvalidOperationException());
  39:             }
  40:             catch (Exception ex)
  41:             {
  42:                 state.Operation.PostOperationCompleted(
  43:                     new SendOrPostCallback(OnDownloadFailed), ex);
  44:             }
  45:         }
  46:     }
  47:  
  48:     /* ... omissis ... */
  49:  
  50:     private class DownloadState
  51:     {
  52:         /// <summary>
  53:         /// Gets or sets the operation.
  54:         /// </summary>
  55:         /// <value>The operation.</value>
  56:         public AsyncOperation Operation { get; set; }
  57:         /// <summary>
  58:         /// Gets or sets the request.
  59:         /// </summary>
  60:         /// <value>The request.</value>
  61:         public HttpWebRequest Request { get; set; }
  62:     }
  63: }

In buona sostanza un attimo prima di avviare il download chiedo al AsyncOperationManager di fornirmi un AsyncOperation. Quest'ultima viene inserita assieme alla Request in una classe DownloadState e al momento giusto viene recuperata per effettuare la sincronizzazione mediante PostOperationCompleted().

In questo modo il componente sarà facilmente riutilzzabile, senza doversi portare dietro una referenza ad un componente di Interfacce...

Technorati Tag: ,

image_3 Infragistic ha lanciato in queste ore un nuovo sito che consente di cercare la giusta soluzione ai più comuni preoblmi di User Interface.

Il suo nome è Quince ed è anche un buon esempio di cosa si possa fare con Silverlight. La ricerca è semplice e ricca di esempi e sono certo che potrà aiutare molti a districarsi nei nella soluzione dei propri problemi di interattività.

Link: http://quince.infragistics.com/

Technorati Tag: ,,

E' di quest'oggi la pubblicazione dei sorgenti dei controlli Silverlight 2.0 RTW presenti in System.Windows.dll. Si tratta di una occasione ottima per imparare meglio come realizzare controlli riusabili che sfruttano appieno i ControlTemplate.

Link:

Technorati Tag: ,

Braulio Diez Botella, un collega spagnolo di Malaga che ho conosciuto durante l'ATE di Barcellona lo scorso anno, mi ha passato il link della sua nuova applicazione Silverlight 2.0. Si tratta di una applicazione per la creazione di Schema di Database online, probabilmente adatta ad un provider di hosting.

Braulio non ha ancora pubblicato il codice sorgente dell'applicazione, che è sicuramente colmo di utili Tricks per chi vuole imparare a programmare con Silverlight, ma ha promesso che dovrebbe farlo nei prossimi mesi dopo una adeguata promozione.

Sul sito è possibile acquisire un account di prova per testare l'applicazione.

Link: http://www.dbschemaeditor.com/

tags: - categories: XAML

Giusto ieri è diventato pubblico un aggiornamento alla datagrid di Silverlight 2.0 che risolve alcuni malfunzionamenti. Nei post che riporto qui sotto trovate i dettagli dell'aggiornamento, le breaking changes e le istruzioni per installare la patch:

http://blogs.msdn.com/brada/archive/2008/12/19/silverlight-2-datagrid-december-2008-release.aspx

http://silverlight.net/forums/t/59990.aspx

Technorati Tags: ,

MIX09_Color_RGB_tag Pensateci bene e rispondete a questo quesito: "cosa potete fare con 10K di codice in Silverlight o WPF?". Per quando la domanda può sembrare assurda, la risposta a questo quesito può essere davvero interessante e le conseguenze anche allettanti.

Si tratta infatti di un nuovo concorso collegato al MIX 2009, tra i cui premi si trovano anche dei biglietti di ingresso alla prestigiosa manifestazione. Il primo premio addirittura vince 3 notti al prestigioso (quanto assurdo) Venetia di Las Vegas e una carta di credito con 1500$.

Aldilà dei premi, sicuramente interessanti, devo dire che mi piace l'idea che sta dietro al concorso, un'idea con un sapore d'altri tempi, in cui davvero sviluppare con i Byte contati era cosa di tutti i giorni.

Ma attenzione che 10K sono di "codice" e non di "compilato". :) Una sfida davvero estrema.

Link: INSPIRE THE WORLD WITH JUST 10K

tags: - categories: XAML

Ecco un interessante progetto che sicuramente può trovare delle applicazioni sia ludiche che professionali. Si tratta di un engine fisico sviluppato per Silverlight 2.0, porting di un framework open source.

Codeplex: http://www.codeplex.com/PhysicsHelper

Home: http://www.andybeaulieu.com/Default.aspx?tabid=67&EntryID=128


Stamattina ho trovato la notizia che è stata rilasciata la versione di Dicembre del porting per Silverlight 2.0 del framework Unity. Unity è un framework per la dependency injection già rilasciato per altri ambienti. Interessante il porting per Silverlight che dovrò sicuremente provare.

Download: Unity Application Block 1.2 for Silverlight - December 2008


Una delle particolarità di Silverlight è che ogni attività rivolta alla rete - sia essa la chiamata ad un metodo di web service piuttosto che il download di un feed rss o quant'altro - deve essere svolto in modo asincrono. Questo comportamento che deriva dal fatto che il plugin non è in grado di fare il rendering quando il thread principale è occupato a svolgere altre attività, è un po' fastidioso perchè impone di gestire le chiamate in due tempi e non sempre questo è semplice e immediato.

Nei giorni scorsi ho trovato una soluzione a questo problema, una tra molte probabilmente, che mi è piaciuta e ho deciso di pubblicarla. Il problema principale che ho voluto risolvere cercando questo tipo di soluzione è la possibilità di riutilizzare facilmente i metodi di un ipotetico layer di comunicazione. Per questo ho rinunciato ad usare un meccanismo basato su eventi sollevati alla ricezione dei risultati perchè questo costringe a continui Attach/Detach degli eventi da parte di diversi componenti della user interface.

Ho utilizzato invece la classe Action<T> che è una diretta parente di Func<T,TResult> con la peculiare differenza di fare riferimento a metodi senza valore di ritorno. Action<T> infatti è un delegate così definito:

   1: public delegate void Action<T>(T obj);

L'idea fondamentale è che ogni volta che si chiama un metodo asincrono ci si trovi di fronte alla possibilità di avere il risultato richiesto oppure una eccezione che indica una condizione di errore. Per questo tipicamente ad ogni metodo farà riferimento un Action<T> per il risultato, dove T è il tipo del risultato e un secondo Action<Exception> per la condizione di errore. La tecnica emula sostanzialmente il comportamento di javascript nella chiamata a metodi di webservice in cui per ognuna delle due possibili condizioni si deve definire un callback che la gestisce.

Il vantaggio è che i metodi da eseguire possono essere scelti ad ogni chiamata e quindi il metodo può essere più facilmente riutilizzabile. Ecco l'implementazione per un ipotetico metodo che restituisce i prodotti da un catalogo:

   1: public static class AppServices
   2: {
   3:     public static void GetProducts(
   4:         Action<ObservableCollection<Product>> successAction, 
   5:         Action<Exception> failAction)
   6:     {
   7:         ProductCatalogClient client = new ProductCatalogClient();
   8:  
   9:         client.GetProductsCompleted += delegate(object sender, GetProductsCompletedEventArgs e)
  10:                                            {
  11:                                                if (e.Error == null)
  12:                                                    successAction.Invoke(e.Result);
  13:                                                else
  14:                                                    failAction.Invoke(e.Error);
  15:                                            };
  16:         client.GetProductsAsync();
  17:     }
  18: }

Per chiamare questo metodo basterà specificare i due metodi di callback che verranno chiamati al termine dell'operazione asincrona. Si tratta a mio parere di una tecnica semplice e flessibile che vale la pena di prendere in considerazione se si deve comunicare spesso con servizi di accesso ai dati. Il codice risultante sarà sicuramente più snello e comprensibile.

tags: - categories: XAML