2016-09-20 72 views
2

你好,我正在尋找一種方法使All方法在異步模式下運行。事實上,我試圖找出如何在LINQ中使用異步的方式。一些linq方法也有異步定義,我不太明白爲什麼不是所有的方法都有異步定義,所以也許有人可以爲我解決問題。LINQ make所有方法async

相關的我試圖讓所有運行異步

版本1

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

2版

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

3版

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

這是我已經試過

的想法是,我有一個IValidator的界面,多重校驗器類實現各自負責其自己的驗證相關的邏輯。在MainValidator類中,我只是想調用All方法來驗證IValidator的列表。

謝謝大家

+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; 
}