Desenvolvimento - C#

ASP.NET MVC 4 e Programação Assíncrona

Este artigo descreve sobre uma das principais novidades presentes na nova versão do ASP.NET MVC: a programação assíncrona, que agora passa a ser mais simples devido aos novos comandos async e await

por Pedro Henrique Barbosa Fernandes



Olá pessoal, hoje vou falar um pouco sobre uma das novidades do novo ASP.NET MVC 4: a programação assíncrona. O grande forte das novas plataformas de desenvolvimento da Microsoft é a programação assíncrona que estará nativa na versão cinco da linguagem de programação C#.

Nas versões anteriores do ASP.NET MVC era possível criar controllers assíncronos herdando a classe AsyncController e usando algumas convenções:

MyActionAsync: método que retorna void e lança um processo assíncrono

MyActionCompleted: método que retorna um ActionResult (neste caso será o resultado da Action MyAction)

Para permitir que o MVC gerencie operações assíncronas e passe o resultado para a View, era necessário usar o AsyncManager do AsyncController.

Por exemplo, o controller abaixo permite obter uma lista de filmes serializada em Json de forma assíncrona a partir de um serviço OData:

public class MoviesController : AsyncController

{

    public ActionResult Index()

    {

        return View();

    }

    public void GetJsonMoviesAsync(int? page)

    {

        const int pageSize = 20;

        int skip = pageSize * ((page ?? 1) - 1);

        string url = string.Format("http://odata.netflix.com/[…]&$skip={0}&$top={1}",

            skip, pageSize);

        //a operação assíncrona é declarada

        AsyncManager.OutstandingOperations.Increment();

        var webClient = new WebClient();

        webClient.DownloadStringCompleted += OnWebClientDownloadStringCompleted;

        webClient.DownloadStringAsync(new Uri(url));//o processo assíncrono inicia

    }

    private void OnWebClientDownloadStringCompleted(object sender,

        DownloadStringCompletedEventArgs e)

    {

          // O processo assíncrono termina

        // "movies" o resultado é adicionado aos parâmetros do AsyncManager

        // Método GetJsonMoviesCompleted

        List<Movie> movies = null;

        if (AsyncManager.Parameters.ContainsKey("movies"))

        {

            movies = (List<Movie>)AsyncManager.Parameters["movies"];

            movies.Clear();

        }

        else

        {

            movies = new List<Movie>();

            AsyncManager.Parameters["movies"] = movies;

        }

        movies.AddRange(Movie.FromXml(e.Result));

        //Fim da operação assíncrona (chama a Action Completed)

        AsyncManager.OutstandingOperations.Decrement();

    }

    public ActionResult GetJsonMoviesCompleted(List<Movie> movies)

    {

        //Retorna o resultado em Json

        return Json(movies, JsonRequestBehavior.AllowGet);

    }

}

Veja agora como podemos criar a mesma operação assíncrona acima, usando o ASP.NET MVC 4 e o C# 5 com as novas palavras chaves async e await, bem mais simples!:

public class MoviesController : AsyncController

{

    public ActionResult Index()

    {

        return View();

    }

    public async Task<ActionResult> GetJsonMovies(int? page)

    {

        const int pageSize = 20;

        int skip = pageSize * ((page ?? 1) - 1);

        string.Format("http://odata.netflix.com/[…]&$skip={0}&$top={1}",

                    skip, pageSize);

        var webClient = new WebClient();

        string xmlResult = await webClient.DownloadStringTaskAsync(url);

        return Json(Movie.FromXml(xmlResult), JsonRequestBehavior.AllowGet);

    }

}

Como você pode observar no código acima, no ASP.NET MVC 4 continua necessário herdar a classe AsyncController mas não há mais convenções de nomenclatura usando métodos que terminam em Completed ou Async.

Pedro Henrique Barbosa Fernandes

Pedro Henrique Barbosa Fernandes