Execução assíncrona é o futuro do desenvolvimento de aplicações para Windows
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, os desenvolvedores tinham que 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 da AsyncManager
// Método GetJsonMoviesCompleted
List movies = null;
if (AsyncManager.Parameters.ContainsKey("movies"))
{
movies = (List)AsyncManager.Parameters["movies"];
movies.Clear();
}
else
{
movies = new List();
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 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 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 ver 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 Completed/Async
Referência:
http://www.juliencorioland.net/Archives/en-aspnet-mvc-4-asynchronous-controllers
Por: Pedro Henrique Barbosa Fernandes (http://pedrofernandes.net)