Alessandro Del Sole's Blog

{ A programming space about Microsoft® .NET® }
posts - 1909, comments - 2047, trackbacks - 352

My Links

News

Your host

This is me! Questo spazio è dedicato a Microsoft® .NET®, di cui sono molto appassionato :-)

Cookie e Privacy

Microsoft MVP

My MVP Profile

Microsoft Certified Professional

Microsoft Specialist

Xamarin Certified Mobile Developer

Il mio libro su VB 2015!

Pre-ordina il mio libro su VB 2015 Pre-ordina il mio libro "Visual Basic 2015 Unleashed". Clicca sulla copertina per informazioni!

Il mio libro su WPF 4.5.1!

Clicca sulla copertina per informazioni! E' uscito il mio libro "Programmare con WPF 4.5.1". Clicca sulla copertina per informazioni!

These postings are provided 'AS IS' for entertainment purposes only with absolutely no warranty expressed or implied and confer no rights.
If you're not an Italian user, please visit my English blog

Le vostre visite

I'm a VB!

Guarda la mia intervista a Seattle

Follow me on Twitter!

Altri spazi

GitHub
I miei progetti open-source su GitHub

Article Categories

Archives

Post Categories

Image Galleries

Privacy Policy

Rendere del codice sincrono "awaitable" con Task.Run

Come avrete visto, in area Video di Visual Basic Tips & Tricks sto pubblicando una nuova serie dedicata al pattern Async/Await per Visual Basic 2012, la cui pubblicazione verrà completata la prossima settimana.

Come avete imparato, la programmazione asincrona con Async/Await si basa sul concetto di task e sulla classe System.Threading.Tasks.Task. Questa classe offre parecchi metodi interessanti, che consentono di gestire attività "awaitable" di vario genere.

Ad esempio, supponiamo di avere del vecchio codice sincrono che però vogliamo eseguire in modalità asincrona sfruttando il nuovo pattern. Partiamo col simulare un lavoro intensivo, banale:

    Private Function SimulateIntensiveWork(token As CancellationToken) _
         
As Integer
        
Dim delay As Integer = 5000
        Threading.
Thread.Sleep(delay)

        
If token.IsCancellationRequested Then
            token.ThrowIfCancellationRequested()
        
End If

        
Return delay
    
End Function

Il codice non fa altro che bloccare il thread per 5 secondi. Così com'è, quest'attività non può essere asincrona. Fortunatamente esiste il metodo Task.Run che esegue il codice specificato in un thread secondario all'interno del Thread Pool. Sostanzialmente, dato questo codice:

    Private Async Function RunIntensiveWorkAsync() As Task
        cancellationToken = 
New CancellationTokenSource
        
'This runs on the UI thread
        
Console.WriteLine("Starting...")

        
Try
            
'This runs on a Thread Pool thread
            
Dim result As Integer = Await Task.Run(Function()
                                                       
Dim workResult As Integer = _
                                                        SimulateIntensiveWork(cancellationToken.Token)
                                                       
Return workResult
                                                   
End Function)
            
'This runs again on the UI thread
            
Console.WriteLine("Finished")
        
Catch ex As OperationCanceledException
            
Console.WriteLine("Canceled by the user.")
        
Catch ex As Exception

        
End Try
        
Console.ReadLine()
    
End Function

Inizio qualcosa nel thread principale, in questo caso in quello della UI. Poi, invocando Task.Run, eseguo il codice in un thread secondario aperto nel Thread Pool. Quando il risultato di questo task è stato ottenuto (da qui l'uso di Await), il thread chiamante continua con il suo lavoro e poiché viene restituito Task, questo metodo può essere awaitato:

    Async Function DoSomething() As Task
        
Await RunIntensiveWorkAsync()
    End Function

In questo modo:

  • vecchio codice sincrono può essere facilmente trasformato in asincrono
  • lo stesso diventa "awaitable" e quindi posso usare Await per attenderne il risultato
  • non devo scrivere codice per creare il thread, eseguirlo, stopparlo

Run vuole un delegate, sia esso passato come lambda che come metodo esplicito puntato con AddressOf. Questo delegate contiene il codice che noi vogliamo sia eseguito in modalità asincrona e che vogliamo rendere awaitable.

Alessandro

Print | posted on venerdì 21 settembre 2012 22:31 | Filed Under [ .NET Framework Visual Basic ]

Powered by:
Powered By Subtext Powered By ASP.NET