使用LINQ select返回异步任务

5
我希望能实现一个从数据库异步返回子项目列表的函数。所以我编写了以下函数:
    public async Task<IEnumerable<object>> GetFiles(int parentId)
    {
        var data = from file in DB.Files
                   where file.ParentId == parentId
                   select new { name = file.Name, id = file.Id };
        return data;
    }

然而,我看到一个警告:异步方法缺少 'await' 运算符,并且将同步运行。如何将此函数重写为异步函数?


1
只是顺便说一下,你从错误的方向来解决问题了。你不应该先“使方法异步”,然后再去想如何做。相反,考虑你的应用程序中所有的I/O操作,让它们使用await,然后再从那里开始扩展。换句话说,在将方法标记为“async”之前,先使用类似于ToListAsync的东西。 - Stephen Cleary
由于我的方法唯一的目的是从数据库获取一些数据,因此它应该从一开始就是异步的。 - Roman Kolesnikov
3个回答

8

你可以使用 ToListAsync()

https://msdn.microsoft.com/en-us/library/dn220258(v=vs.113).aspx

var data = await DB.Files
    .Where(file => file.ParentId == parentId)
    .Select
        (
            new 
            { 
                name = file.Name,
                id = file.Id 
            }
        ).ToListAsync();
return data;

或者:

var data = from file in DB.Files
           where file.ParentId == parentId
           select new { name = file.Name, id = file.Id };
return await data.ToListAsync();

请注意,这将查询数据。此外,您可能需要重新考虑您的方法名称。当一个方法是异步的naming convention建议您在方法名称后添加“Async”。
按照惯例,在具有 Async 或 async 修饰符的方法名称后附加“Async”。

6

ToListAsync() 方法不再与可枚举类型一起使用。您可以像下面这样使用FromResult方法:

var data = from file in DB.Files
           where file.ParentId == parentId
           select new { name = file.Name, id = file.Id };
    return await Task.FromResult(data);

你的回答毫无意义,因为根据你提供的关于ToListAsync的链接文档,它返回一个Task<List>,而List类实现了IEnumerable。所以是的,ToListAsync的返回值是可枚举的。 - Esko

-2

或者您可以使用TaskCompletionSource -

public static async Task<string> ReturnAsync()
{
    var tsc = new TaskCompletionSource<string>();
    tsc.SetResult("hello world");
    return await tsc.Task;
} 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接