C#异步选择

时间:2019-05-16 02:30:14

标签: c# linq

我有以下工作代码:

var failures = _validators
    .Select(v => v.Validate(request))
    .SelectMany(result => result.Errors)
    .Where(f => f != null)
    .ToList();

Validate方法返回一个ValidationResult对象。

我想将Validate方法更改为ValidateAsync,然后在async/await内使用Select。现在,它不返回IEnumerable<ValidationResult>,而是返回IEnumerable<Task<ValidationResult>>,并且SelectMany调用不再起作用。

所以我更改了这样的代码:

var failures = _validators
    .Select(async v => await v.ValidateAsync(request))
    .SelectMany(result => result.Result.Errors)
    .Where(f => f != null)
    .ToList();

我正在使用Result对象的Task属性来访问ValidationResult对象。

我记得很久以前就读过一些有关使用Task.Result的内容,这可能会导致死锁。这个解决方案好还是有更好的解决方案?

1 个答案:

答案 0 :(得分:3)

我使用此扩展名:

public static async Task<TResult[]> SelectAsync<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, Task<TResult>> selector)
{
    if (source == null)
    {
        throw new ArgumentNullException(nameof(source));
    }

    if (selector == null)
    {
        throw new ArgumentNullException(nameof(selector));
    }

    return await Task.WhenAll(source.Select(selector));
}

var temp = await _validators
    .SelectAsync(v => v.ValidateAsync(request));

var result = temp.SelectMany(result => result.Errors)
    .Where(f => f != null)
    .ToList();