Non sarà in grado di utilizzare la sintassi di query o l'operazione let
, ma è possibile scrivere un metodo per eseguire più operazioni per ogni elemento in parallelo:
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);
});
}
Questo permetterebbe di scrivere:
var query = list.AsParallel()
.SelectAll(LongRunningCalc1,
LongRunningCalc2,
(a, b) => new {a, b})
È possibile aggiungere sovraccarichi per le operazioni parallele supplementari pure:
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);
});
}
E 'possibile scrivere una versione di gestire un numero di selettori non noti al momento della compilazione, ma per fare che tutti hanno bisogno di calcolare un valore dello stesso tipo:
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);
}
Questa non è la mia area di esperti, ma non è necessario attendere i risultati delle attività? – Magnus
@Magnus Sono già d'accordo. – Servy
Yeh che chiama '.Result' attende l'esecuzione del Task. Ho semplificato un po 'il mio codice di esempio, ma questo mi ha messo sulla strada giusta, grazie per l'aiuto. – Lyall