2010-11-13 13 views
5

Come creare una vera pipeline di funzioni utilizzando C#? Ho qualche idea, come i seguenti, ma non è un vero e proprio oleodottoCome implementare la vera pipeline di funzioni in C#?

public static IEnumerable<T> ForEachPipeline<T>(this IEnumerable<T> source, params Func<T, T>[] pipeline) 
{ 
foreach (var element in source) { 
    yield return ExecutePipeline(element, pipeline); 
} 
} 

private static T ExecutePipeline<T>(T element, IEnumerable<Func<T, T>> jobs) 
{ 
var arg = element; 
T result = default(T); 
foreach (var job in jobs) { 
    result = job.Invoke(arg); 
    arg = result; 
} 
return result; 
} 

Nel codice sopra ogni elemento di IEnumerable<T> sarebbe in grado di ottenere nella pipeline solo dopo che l'elemento precedente termina l'esecuzione di tutte le funzioni (ad esempio uscite la pipeline), ma secondo la definizione se element1 termina l'esecuzione di func1 e inizia l'esecuzione di func2, a quel punto dovrebbe iniziare l'esecuzione di func1 e così via mantenendo così il flusso continuo di dati nella pipeline.

Questo tipo di scenario è possibile implementare in C#? Se possibile, dammi qualche codice di esempio.

+0

Esiste solo un singolo contesto di esecuzione a meno che non vengano introdotti i thread (l'approccio alternativo con un thread singolo è solo la generazione di risultati non pigro ad ogni passaggio). Con i thread, ogni fase è solo una coda FIFO che trasmette messaggi attorno a una "pompa". I thread (in realtà, la concorrenza) aumentano notevolmente la complessità, forse si vedono i metodi .NET4 "Parallel". –

+0

Non ho problemi nell'introdurre discussioni, ho bisogno che il lavoro sia fatto comunque .. per favore condividi alcune idee –

+0

PLINQ non risolverebbe già questo? http://msdn.microsoft.com/en-us/library/dd460688.aspx – bzlm

risposta

0

Dal commento: Esiste un solo contesto di esecuzione a meno che non vengano introdotti i thread (l'approccio alternativo con un thread singolo è solo la generazione di risultati non pigro ad ogni passaggio). Con i thread, ogni fase è solo una coda FIFO che trasmette messaggi attorno a una "pompa". I thread (in realtà, la concorrenza) aumentano notevolmente la complessità, forse si vedono i metodi .NET4 "Parallel".

Un metodo "facile" è solo per configurare N "avvia" utilizzando Parallel.ForEach - se e solo se è possibile garantire che i calcoli sono privi di effetti collaterali.

Modifica: Vedere i commenti.

+0

Questa era un'idea, ma in questo modello come faccio a garantire che il risultato Enumerable sia nello stesso ordine della sorgente Enumerable? –

+1

@AnindyaChatterjee: Invece di usare 'Parallel.ForEach' usa Parallel Linq (PLINQ) tramite i metodi di estensione' ParallelEnumerable', che includono ['AsOrdered'] (http://msdn.microsoft.com/en-us/library /dd642142.aspx) per mantenere l'ordine di input. – Richard

0

Questo comportamento è più efficiente di una vera pipeline. Il pipelining ha senso solo se le operazioni possono essere eseguite in parallelo, ma tutti questi lavori condividono un singolo thread della CPU e quindi devono essere eseguiti in sequenza anche se pipeline.

Se capisci che non ci saranno miglioramenti delle prestazioni e vuoi ancora fare pipeline, lascia un commento e ti mostrerò come, ma prima voglio assicurarmi di sapere cosa stai chiedendo.

+0

Perché pensi che la vera pipeline non aumenti il ​​throughput? Ad ogni modo sono molto interessato a vedere una vera implementazione della pipeline e controllerò me stesso il rendimento dei due. –

0

Credo che manchi un elemento architettonico principale, che il lavoro sia gestito o meno. Pipeline è molto simile alla catena GoF tradizionali di responsabilità, date un'occhiata qui se non si ha il libro GoF intorno:

http://www.dofactory.com/Patterns/PatternChain.aspx#_self1

Credo che bisogna per restringere la "T" in una certa interfaccia che indica la pipeline se il lavoro è stato gestito (utilizzare l'istruzione "where").

Inoltre, dai un'occhiata al framework PLINQ. So che non è esattamente quello che stai cercando (lì, l'intento è di eseguire diversi lavori in parallelo), ma potrebbe darti delle buone idee.

+0

Se applico questo modello sarà uguale al codice che ho menzionato sopra, non sarà comunque un vero gasdotto. –

Problemi correlati