2016-09-20 3 views
2

Привет, я ищу способ заставить весь метод работать в асинхронном режиме. На самом деле я пытаюсь понять способ использования async всякий раз, когда мне это нужно в LINQ. Некоторые методы linq также имеют асинхронное определение, и я не совсем понимаю, почему не все методы имеют асинхронное определение, поэтому, возможно, кто-то может очистить меня.LINQ make All method async

Связанные мне пытается сделать все бегут асинхронной

Версия 1

async Task<bool> IHrtbProfileValidator.ValidateHrtb(UserHrtbProfileDTO dto_Hrtb) 
     { 
      var x = _validator.All(async (ck) => await ck.ValidateHrtb(dto_Hrtb)); 
      return x; 
     } 

Version 2

var x = _validator.All((ck) => await ck.ValidateHrtb(dto_Hrtb)); 

Version 3

var x = _validator.All(async (ck) => await ck.ValidateHrtb(dto_Hrtb).Result); 

это то, что я пытался

Идея заключается в том, что у меня есть интерфейс IValidator, из которого несколько классов валидаторов реализовать каждый из которых отвечает со своей собственной логикой, связанные с проверки. В классе MainValidator я просто хочу вызвать метод All для проверки списка идентификаторов.

Спасибо всем

+1

LINQ не имеет * любые * асинхронные методы. Это язык запроса *, он фактически не выполняет запрос. Вы смешиваете его с Entity Framework и его асинхронными методами, например 'ToListAsync' –

ответ

2

Вы не можете сделать All метод сам асинхронной, но то, что вы можете сделать, это сделать Select, ждать результата, а затем передать этот результат All

async Task<bool> IHrtbProfileValidator.ValidateHrtb(UserHrtbProfileDTO dto_Hrtb) 
{ 
    IEnumerable<Task<bool>> items = _validator.Select(ck => ck.ValidateHrtb(dto_Hrtb)); 
    bool[] results = await Task.WhenAll(items); 
    var x = results.All(item => item); 
    return x; 
} 

Другой вариант вы можете создать свой собственный метод расширения AllAsync, который работает с задачами в качестве источников или предикатов.

public static class ExtensionMethods 
{ 
    // This is for async predicates with either a sync or async source. 
    // This is the only one you need for your example 
    public static async Task<bool> AllAsync<TSource>(this IEnumerable<TSource> source, Func<TSource, Task<bool>> predicate) 
    { 
     if (source == null) 
      throw new ArgumentNullException(nameof(source)); 
     if (predicate == null) 
      throw new ArgumentNullException(nameof(predicate)); 
     foreach (var item in source) 
     { 
      var result = await predicate(item); 
      if (!result) 
       return false; 
     } 
     return true; 
    } 

    // This is for synchronous predicates with an async source. 
    public static async Task<bool> AllAsync<TSource>(this IEnumerable<Task<TSource>> source, Func<TSource, bool> predicate) 
    { 
     if (source == null) 
      throw new ArgumentNullException(nameof(source)); 
     if (predicate == null) 
      throw new ArgumentNullException(nameof(predicate)); 
     foreach (var item in source) 
     { 
      var awaitedItem = await item; 
      if (!predicate(awaitedItem)) 
       return false; 
     } 
     return true; 
    } 
} 

Вы могли бы сделать

async Task<bool> IHrtbProfileValidator.ValidateHrtb(UserHrtbProfileDTO dto_Hrtb) 
{ 
    var x = await _validator.AllAsync((ck) => ck.ValidateHrtb(dto_Hrtb)); 
    return x; 
}