Etiquetado: LINQ

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