如何在addrange select语句中添加异步"await"?

Ben*_*Ben 5 .net c# select task-parallel-library async-await

我有这样的功能:

public async Task<SomeViewModel> SampleFunction()
{
    var data = service.GetData();
    var myList = new List<SomeViewModel>();

    myList.AddRange(data.select(x => new SomeViewModel
    {
        Id = x.Id,
        DateCreated = x.DateCreated,
        Data = await service.GetSomeDataById(x.Id)
    }

    return myList;
}
Run Code Online (Sandbox Code Playgroud)

await没有工作,因为它只能用于使用async修饰符标记的方法或lambda .我在哪里放置async这个功能?

i3a*_*non 10

您只能awaitasync方法/委托内使用.在这种情况下,您必须将该lambda表达式标记为async.

但等等,还有更多......

Select是来自前async时代,所以它不处理asynclambda(在你的情况下,它会返回IEnumerable<Task<SomeViewModel>>而不是IEnumerable<SomeViewModel>你真正需要的).

但是,您可以自己添加该功能(最好是作为扩展方法),但是您需要考虑是否希望await每个项目在进入下一个(顺序)或await所有项目结束之前(并发).

顺序 async

static async Task<TResult[]> SelectAsync<TItem, TResult>(this IEnumerable<TItem> enumerable, Func<TItem, Task<TResult>> selector)
{
    var results = new List<TResult>();
    foreach (var item in enumerable)
    {
        results.Add(await selector(item));
    }
    return results.ToArray();
}
Run Code Online (Sandbox Code Playgroud)

同时 async

static Task<TResult[]> SelectAsync<TItem, TResult>(this IEnumerable<TItem> enumerable, Func<TItem, Task<TResult>> selector)
{
    return Task.WhenAll(enumerable.Select(selector));
}
Run Code Online (Sandbox Code Playgroud)

用法

public Task<SomeViewModel[]> SampleFunction()
{
    return service.GetData().SelectAsync(async x => new SomeViewModel
    {
        Id = x.Id,
        DateCreated = x.DateCreated,
        Data = await service.GetSomeDataById(x.Id)
    }
}
Run Code Online (Sandbox Code Playgroud)