Multithreading in Silverlight 2.0: operazioni asincrone in background

di Alessio Leoncini, in Silverlight 2.0,

Analogamente alle altre applicazioni .NET anche in Silverlight è possibile distribuire le operazioni su più thread rispetto a quello dell'interfaccia utente.

Per ogni applicazione sono disponibili un insieme di thread, un pool, gestiti dalla classe ThreadPool; questa classe mette a disposizione una serie di strumenti per l'uso dei thread per quelle operazioni particolamente lunghe in modo da non bloccare l'uso dell'interfaccia utente.

Con il metodo QueueUserWorkItem è possibile mettere in coda più operazioni in modo da demandare al ThreadPool la distribuzione su più thread, l'uso è molto semplice:

string pageName;
string baseUri;
string feedUri;

private struct FeedLoadInfo
{
    public string feedUri { get; set; }
    public ListBox listBox { get; set; }
}

public Page()
{
    InitializeComponent();

    pageName = System.IO.Path.GetFileName(HtmlPage.Document.DocumentUri.AbsolutePath);
    baseUri = HtmlPage.Document.DocumentUri.AbsoluteUri.Replace(pageName, String.Empty);
    feedUri = string.Format("{0}silverlightitaliafeed.xml", baseUri);

    FeedLoadInfo inf1 = new FeedLoadInfo();
    inf1.feedUri = feedUri;
    inf1.listBox = fistListBox;

    ThreadPool.QueueUserWorkItem(getFeed, inf1);
}

void getFeed(object loadInfo)
{
    FeedLoadInfo info = (FeedLoadInfo)loadInfo;
    WebClient client = new WebClient();
    client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);
    client.OpenReadAsync(new Uri(info.feedUri), info.listBox);
}

void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
    ListBox list = e.UserState as ListBox;
    Stream stream = e.Result;
    StreamReader streamReader = new StreamReader(stream);
    XmlReader reader = XmlReader.Create(streamReader);
    SyndicationFeed feeds = SyndicationFeed.Load(reader);

    Thread.Sleep(3000);

    Dispatcher.BeginInvoke(() => UpdateList(list, feeds));
}

void UpdateList(ListBox list, SyndicationFeed feeds)
{
    list.ItemsSource = feeds.Items;
}

Nell'esempio viene richiesta l'esecuzione di getFeed su un thread di background attraverso il metodo ThreadPool.QueueUserWorkItem(getFeed, inf1); al metodo può essere passato un oggetto che contenga le informazioni utili all'esecuzione del processo. In questo caso viene passato un oggetto che contiente l'url del feed da interrogare ed il riferimento alla ListBox nel quale renderizzare i dati.

Dopo la chiamata del metodo QueueUserWorkItem l'interfaccia utente rimane disponibile all'utente e prosegue nelle proprie operazioni.
Il metodo getFeed esegue una chiamata asincrona ad una risorsa RSS, al termine del caricamento vengono eseguite una serie di operazioni, per simulare il prolungamento di questi processi è stato inserito un Thread.Sleep di tre secondi.

Il metodo getFeed viene eseguito in un thread diverso da quello dell'interfaccia utente, per consentire una loro interazione è necessario utilizzare l'oggetto Dispacher in modo da mettere in coda tutte quelle operazioni che portino i dati verso l'UI.
Nel codice viene utilizzato un delegate anonimo per l'esecuzione del popolamento della ListBox corrispondente.

In questo esempio https://www.silverlightitalia.com/script/demo/22/default.html è messa a confronto l'esecuzione di getFeed su un thread di background rispetto all'esecuzione sul thread dell'interfaccia utente: a differenza del procedimento appena illustrato, il caricamento dei dati della ListBox di destra blocca completamente l'interfaccia e l'animazione in corso.

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

Nessuna risorsa collegata

I più letti di oggi