如何将以下内容转换为Async Linq调用。我知道LINQ对Async调用没有最好的效果,SelectMany直接无效。我现在运气好了很多东西。谢谢。
我如何将其转换为ASYNC电话?
public class Foo
{
public int Id { get; set; }
public int? ParentId { get; set; }
// other props
}
You can get children of one item using:
List<Foo> GetChildren(List<Foo> foos, int id)
{
return foos
.Where(x => x.ParentId == id)
.Union(foos.Where(x => x.ParentId == id)
.SelectMany(y => GetChildren(foos, y.Id))
).ToList();
}
For ex.
List<Foo> foos = new List<Foo>();
foos.Add(new Foo { Id = 1 });
foos.Add(new Foo { Id = 2, ParentId = 1 });
foos.Add(new Foo { Id = 3, ParentId = 2 });
foos.Add(new Foo { Id = 4 });
GetChild(foos, 1).Dump(); // will give you 2 and 3 (ids)
答案 0 :(得分:0)
LINQ使用async-await完美运行。我认为你的错误观念是 因为在实际执行查询时您不清楚。
您不会说明您是使用Iqueryable
还是IEnumerable
,但原则保持不变。
有两种LINQ语句:只会更改查询的语句和将执行查询的语句。
您可以看到linq语句属于哪个组(串联)。如果结果为IEnumerable<TResult>
或IQueryable<TResult>
,则仅创建查询。它尚未执行。尚未访问数据库(或者在文件的情况下:未读取文件的内容)。
如果结果是List<TResult>
,一个TResult
或Boolean
等,那么不是IEnumerable
,那么查询实际上就会执行。或者更确切地说:GetEnumerator
和MoveNext
已被调用,数据实际上被提取并放入结果中。
第一组的方法有Where
,Select
,&#39; Union&#39; GroupJoin&#39;,GroupBy
等。
第二组的方法是ToList
,ToDictionary
,还有FirstOrDefault
和Any
。调用这些函数时,实际访问数据库,或实际处理文件内容等。
更改查询的方法并不耗时。因此,使这些功能等待是没有用的。但是,查询等待数据库(等)是非常有用的。因此,您可以找到它们的异步版本。例如,您可以找到IQueryable.ToListAsync,IQueryable.ToDictionaryAsync,IQueryable.FirstOrDefaultAsync甚至IQueryable.AnyAsync
等方法返回查询:
Task<List<Foo>> GetChildrenAsync(IEnumerable<Foo> foos, int id)
{
var query = foos.Where(foo => foo.ParentId == id)
.Union(foos
.Where(foo => foo.ParentId == id)
.SelectMany(foo => GetChildren(foos, y.Id));
// until now only the query has been created.
// collection foos has not been accessed yet.
// execute the query:
var result = await query.ToListAsync();
return result;
}
如果按照这些较小的步骤划分语句,则可以更轻松地使用调试器查看实际调用GetEnumerator的时间。如果需要,您当然可以将其改为一个重要声明。
顺便说一句,如果您的输入真的是List?在这种情况下,我相当肯定,使你的功能等待是没有用的。 async-await仅在您的线程必须等待另一个线程或进程完成才能继续之前有用。但这超出了这个问题的范围。