2013-04-12 11 views
5

Vorrei sapere se è possibile modificare lo stato di completamento dei blocchi di dati?Task Flusso dati, un blocco dati può essere modificato dallo stato di completamento?

Ad esempio, ho contrassegnato un blocco dati var block = new BufferBlock<int>(); completo di block.Complete(). Il blocco è collegato ad altri blocchi di dati. Vorrei sapere se riesco a eseguire lo block modificando lo stato di completamento allo stato originale! Completo.

Se ciò non è possibile, come posso eseguire più esecuzioni, incluso il completamento, senza dover a) scollegare tutti i blocchi, b) riattivare tutti i blocchi e c) ricollegare tutti i blocchi nuovamente?

Qualsiasi idea che possa facilitare l'esecuzione dei cicli di flusso dei dati, compreso il completamento di ciascun blocco lungo la catena senza dover ricreare l'intero framework?

Grazie

+1

Perché hai bisogno di corse separate? Inoltre, perché non vuoi ricreare la rete del flusso di dati? Dubito che influenzerà le prestazioni (a meno che non lo faccia molte volte al secondo) e inoltre non dovrebbe rendere il tuo codice più complicato di molto. – svick

+0

Le corse separate fanno parte del requisito. Ricreare l'intera rete vanificherebbe completamente l'efficienza ottenuta attraverso la scelta del flusso di dati tpl. Il mal di testa principale è lo scollegamento e il ricollegamento non tanto della ri-creazione di ciascun blocco di flusso di dati. Se la modifica dello stato di completamento è impossibile, come potrei altrimenti segnalare il completamento senza influire sullo stato di completamento di ogni blocco del flusso di dati? Non posso semplicemente inviare una bandiera atomica perché i tipi di oggetto lungo la catena non sono identici (ci sono trasformabili coinvolti). –

risposta

3

No, non è possibile “incompleta” un blocco di flusso di dati completata. Penso che quello che dovresti fare è aggiungere una bandiera a ciascun messaggio che dice se è l'ultimo messaggio in una corsa. Per rendere più semplice lavorare con esso, è possibile creare set di metodi di supporto come:

public static TransformBlock<Tuple<TInput, bool>, Tuple<TOutput, bool>> 
    CreateEnhancedTransformBlock<TInput, TOutput>(Func<TInput, TOutput> transform) 
{ 
    return new TransformBlock<Tuple<TInput, bool>, Tuple<TOutput, bool>>(
     tuple => Tuple.Create(transform(tuple.Item1), tuple.Item2)); 
} 

In questo modo, si entra in un delegato transform che si occupa solo con TInput e TOuput e la bandiera viene trasferito insieme ad ogni messaggio.

+0

Idea interessante, ti piacerebbe commentare l'overhead computazionale durante l'esecuzione andando su questa rotta? Finora vedo solo un ulteriore controllo sul "flag di completamento" del blocco ricevente per ogni messaggio in arrivo. Qualcos'altro che sto omettendo? Sarebbe più costoso spedire invece un enum piuttosto che un bool? In tal modo potrei comunicare altri stati oltre al semplice completamento. –

+1

@Freddy Ci potrebbe essere un piccolo sovraccarico poiché ci sono due invocazioni di delegati invece di uno, ma questo dovrebbe essere davvero trascurabile. E penso che sostituire il 'bool' con un enum non dovrebbe influenzare la performance. – svick

+0

sicuramente una buona idea per risolvere questo problema, ma alla fine sono andato con il tuo primo consiglio: ho letto attentamente la funzione di completamento dei blocchi di dati e ricreato l'intera pipeline. Fornisco i callback al blocco di dati upstream contenente i moduli e al completamento di ogni blocco di dati lo ricrea di nuovo e lo consegna attraverso il callback a valle dove i due blocchi sono ricollegati. –

Problemi correlati