C# 异步选择

RBa*_*iak 2 c# linq

我有以下工作代码:

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

Validate方法返回一个ValidationResult对象。

我想将Validate方法更改为ValidateAsync,然后我async/awaitSelect. 现在,它不会返回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();
Run Code Online (Sandbox Code Playgroud)

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

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

Bac*_*cks 6

我使用这个扩展:

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();
Run Code Online (Sandbox Code Playgroud)