Consultas asíncronas LINQ mediante extensiones


Una parte que falta por ahora en LINQ es una forma directa de ejecutar una query de forma asíncrona.
Si tenemos una query cualquiera como por ejemplo:

var query = from media in context.MediaFiles
           select new MediaItem
           {
               Title=media.Title,
               Path = media.Path,
               MimeType = media.MimeType,
               Date=media.CreationTime,
               Size=media.Length
           };

Para ejecutar la consulta en modo asíncrono no tenemos ningún método asíncrono directamente (no confundir con paralelo como en PLINQ) y tenemos que meterlo en una Task:

var result = await Task<List<MediaItem>>.Run(() =>
{
    return query.ToList();
});

Para no tener que escribir tantas veces la creación de Task podemos meter ese código en un método de extensión, gracias a que tenemos generics:

public static class QueryExtensions
{
    public static Task<List<T>> ToListAsync<T>(this IQueryable<T> query)
    {
        return Task<List<T>>.Run(() =>
        {
           return query.ToList();
        });
    }
}

Como bien dice Kenneth en el comentario, en la extensión no nos hace falta el async/await, pues la Task es por definición “awaitable”

Ahora ya podemos escribir la llamada de forma más clara:

var mediaFiles = await query.ToListAsync();

Con este sistema podremos ir creando todos los que necesitemos en una clase de extensión para su uso con cualquier elemento IQueryable.

Anuncios

  1. Kenneth Truyers

    Muy buena idea Juanma!. Se podría mejorar quitando el async/await en la extensión. Ya que el Task.Run devuelve un Task no es necesario usar el async/await. Esto crearía un overhead para el CLR que afecta la performancia. La diferencia es muy pequeña pero existe.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s