您將無法使用查詢語法或let
操作,但你可以寫並行執行的每個項目多個操作的方法:
public static ParallelQuery<TFinal> SelectAll<T, TResult1, TResult2, TFinal>(
this ParallelQuery<T> query,
Func<T, TResult1> selector1,
Func<T, TResult2> selector2,
Func<TResult1, TResult2, TFinal> resultAggregator)
{
return query.Select(item =>
{
var result1 = Task.Run(() => selector1(item));
var result2 = Task.Run(() => selector2(item));
return resultAggregator(result1.Result, result2.Result);
});
}
這將使你寫:
var query = list.AsParallel()
.SelectAll(LongRunningCalc1,
LongRunningCalc2,
(a, b) => new {a, b})
你可以額外的並行操作添加過載以及:
public static ParallelQuery<TFinal> SelectAll<T, TResult1, TResult2, TResult3, TFinal>
(this ParallelQuery<T> query,
Func<T, TResult1> selector1,
Func<T, TResult2> selector2,
Func<T, TResult3> selector3,
Func<TResult1, TResult2, TResult3, TFinal> resultAggregator)
{
return query.Select(item =>
{
var result1 = Task.Run(() => selector1(item));
var result2 = Task.Run(() => selector2(item));
var result3 = Task.Run(() => selector3(item));
return resultAggregator(
result1.Result,
result2.Result,
result3.Result);
});
}
它可以寫一個版本來處理一些在編譯的時候不知道選擇的,但要做到這一點,他們都需要計算出相同類型的值:
public static ParallelQuery<IEnumerable<TResult>> SelectAll<T, TResult>(
this ParallelQuery<T> query,
IEnumerable<Func<T, TResult>> selectors)
{
return query.Select(item => selectors.AsParallel()
.Select(selector => selector(item))
.AsEnumerable());
}
public static ParallelQuery<IEnumerable<TResult>> SelectAll<T, TResult>(
this ParallelQuery<T> query,
params Func<T, TResult>[] selectors)
{
return SelectAll(query, selectors);
}
這不是我的專家領域,但你不需要等待任務的結果? – Magnus 2014-10-28 17:56:13
@Magnus我已經是。 – Servy 2014-10-28 17:58:15
Yeh調用'.Result'等待任務執行。我簡單地簡化了我的示例代碼,但這使我走上了正確的道路,感謝您的幫助。 – Lyall 2014-10-28 18:01:53