2016-11-03 33 views
1

我有種子與異步(獲得從種子有效載荷)混合LINQ

var seeds = new [] {1, 2, 3, 4}; 

從每個種子我想運行執行一些計算與種子異步方法的集合:

async Task<int> Calculation(int seed); 

我的目標是進行選擇這樣的:

var results = from seed in seeds 
       let calculation = await Calculation(seed) 
       select new { seed, calculation }; 

不幸的是,這句法沒有使用LINQ不允許的。

如何讓「結果」變量包含種子和計算?

(我將不勝感激任何答案,但特別是如果它使用System.Reactive的Observable

+0

http://stackoverflow.com/questions/21868087/how-to-await- a-list-of-tasks-asynchronously-using-linq這裏由斯蒂芬·克萊裏回答,關於它。 – mybirthname

回答

3

這裏是一個解決方案的Rx:

var seeds = new [] {1, 2, 3, 4}; 
var results = Observable.ToObservable(seeds) 
    .SelectMany(async i => new { seed = i, calculation = await Calculation(i)}) 
    .ToEnumerable(); 
1

更改異步函數返回兩個計算出的數量和給定seed

public static async Task<Output> Calculation(int seed) 
{ 
    return new Output { Seed = seed, Result = 0 }; 
} 

public class Output 
{ 
    public int Seed { get; set; } 
    public int Result { get; set; } 
} 

然後使用LINQ返回一個Task[]可以在其上WaitAllWhenAllWaitAll vs WhenAll

var seeds = new[] { 1, 2, 3, 4 }; 

var tasks = seeds.Select(Calculation); 
var results = await Task.WhenAll(tasks); 

foreach (var item in results) 
    Console.WriteLine($"seed: {item.Seed}, result: {item.Result}"); 
+0

'WhenAlll'有一個超載,需要一個'Enumerable <任務>',不需要調用ToArray() –

+0

@ScottChamberlain - 你是對的:)謝謝:)修正了它。最初我使用了'WaitAll'並且必須傳遞一個數組..但忘記在更改時更新 –

2

你可以做以下使用WhenAll靜態方法:

var r= await Task.WhenAll(seeds.Select(async seed =>new { 
                  Seed= seed, 
                  Result = await Calculation(seed) 
                 } 
            ) 
         ); 
+2

在這裏沒有理由使用'Task.Run'。 – Servy

+0

嗨@Servy,謝謝指出,這是我的上次更新是否正確? – octavioccl

+0

您也可以用lambda表達式替換lambda表達式,並且只是內聯計算調用,簡化了代碼。格式也...不理想。 – Servy