Il presente articolo è stato tradotto automaticamente. Passare il puntatore sulle frasi nell'articolo per visualizzare il testo originale. Ulteriori informazioni.
Traduzione
Originale
Questo argomento non è stato ancora valutato - Valuta questo argomento

Flusso di dati (Task Parallel Library)

.NET Framework 4.5

La libreria Task Parallel Library (TPL) fornisce componenti del flusso di dati per aumentare l'affidabilità di concorrenza applicazioni abilitate. Questi componenti del flusso di dati sono definite collettivamente la raccolta di flusso di libreria TPL. Questo modello di flusso di dati favorisce la programmazione basata su attori fornendo il passaggio dei messaggi in-process per il flusso di dati con granularità grossolana e canalizzando le attività. La compilazione dei componenti del flusso di dati sui tipi e un'infrastruttura di programmazione di libreria TPL e si integrano con il C#, Visual Basice il supporto del linguaggio F# per la programmazione asincrona. Questi componenti del flusso di dati sono utili quando si dispone di più operazioni che devono comunicare tra loro in modo asincrono o quando si desidera elaborare i dati quando diventano disponibili. Ad esempio, si consideri un'applicazione che elabora i dati immagine da una fotocamera Web. Tramite il modello di flusso di dati, l'applicazione può elaborare i frame di immagine non appena diventano disponibili. Se l'applicazione aggiorna i frame di immagine, ad esempio, eseguendo la correzione o la riduzione occhi rossi leggera, è possibile creare una pipeline di componenti del flusso di dati. Ogni fase della pipeline può utilizzare la funzionalità più con granularità grossolana di parallelismo, come la funzionalità fornita dalla libreria TPL, per trasformare l'immagine.

In questo documento viene fornita una panoramica della raccolta di flusso di libreria TPL. Viene descritto il modello di programmazione, i tipi di blocchi predefiniti del flusso di dati e come configurare i blocchi del flusso di dati soddisfare esigenze specifiche delle applicazioni.

Suggerimento Suggerimento

La raccolta di flusso di libreria TPL (spazio dei nomi diSystem.Threading.Tasks.Dataflow ) non viene distribuito con .NET Framework 4.5. Per configurare lo spazio dei nomi System.Threading.Tasks.Dataflow, aprire il progetto in Visual Studio 2012, scegliere Gestisci pacchetti NuGet dal menu Progetto e cercare online il pacchetto Microsoft.Tpl.Dataflow.

Il documento include le sezioni seguenti:

La raccolta di flusso di libreria TPL fornisce una base per il passaggio dei messaggi e parallelizzare applicazioni dei/O-intensive e elevato utilizzo della CPU con la velocità effettiva elevata e bassa latenza. Anche in è controllo esplicito su come i dati vengono memorizzati nel buffer e scorrere nel sistema. Per comprendere il modello di programmazione dataflow, si consideri un'applicazione che viene caricato in modo asincrono le immagini dal disco e crea un insieme delle immagini. I modelli di programmazione tradizionale richiedono in genere di utilizzare i callback e gli oggetti di sincronizzazione, come blocchi, attività e all'accesso di coordinate ai dati condivisi. Tramite il modello di programmazione dataflow, è possibile creare oggetti del flusso di dati e immagini considerate come vengono letti dal disco. Nel modello di flusso di dati, dichiarate come i dati vengono gestiti quando diventano disponibili e anche tutte le dipendenze tra i dati. Poiché le dipendenze tra i dati, è possibile evitare spesso la necessità di sincronizzare l'accesso ai dati condivisi. Inoltre, poiché il lavoro runtime di pianificazioni base all'origine asincrono di dati, il flusso può migliorare la risposta e la velocità effettiva efficiente dei thread sottostante. Per un esempio che utilizza il modello di programmazione dataflow per implementare l'elaborazione di immagini in un'applicazione Windows Form, vedere Procedura dettagliata: utilizzo del flusso di dati in un'applicazione Windows Form.

Hh228603.collapse_all(it-it,VS.110).gifOrigini e destinazioni

La raccolta di flusso di libreria TPL è costituito dai blocchi delflusso di dati, che sono strutture di dati che memorizza nel buffer ed elaborano i dati. La libreria TPL definisce tre tipi di blocchi del flusso di dati: blocchi di origine, blocchi di destinazionee blocchi di propagazione. Un blocco di origine funge da origine dei dati e può essere letto da. Un blocco di destinazione funge da destinatario dei dati e può essere scritto su. Un blocco di propagazione funge sia da blocco di origine che un blocco di destinazione e può essere letto da e scritti su. La libreria TPL definisce l'interfaccia System.Threading.Tasks.Dataflow.ISourceBlock<TOutput> per rappresentare i database di origine, System.Threading.Tasks.Dataflow.ITargetBlock<TInput> per rappresentare le destinazioni e System.Threading.Tasks.Dataflow.IPropagatorBlock<TInput, TOutput> per rappresentare i propagatori. IPropagatorBlock<TInput, TOutput> eredita da entrambe le ISourceBlock<TOutput>e da ITargetBlock<TInput>.

La raccolta di flusso di libreria TPL fornisce vari tipi di blocchi predefiniti del flusso di dati che implementano ISourceBlock<TOutput>, ITargetBlock<TInput>e le interfacce IPropagatorBlock<TInput, TOutput>. Questi tipi di blocco del flusso di dati sono descritti in questo documento nella sezione Tipi di blocchi predefiniti del flusso di dati.

Hh228603.collapse_all(it-it,VS.110).gifConnettere blocchi

È possibile connettere i blocchi del flusso di dati per creare pipeline, che sono sequenze lineari di blocchi del flusso di dati, o reti, ovvero grafici dei blocchi del flusso di dati. Una pipeline è un form di rete. In una pipeline o una rete, i database di origine in modo asincrono si spostano i dati per i database di destinazione come tali dati diventano disponibili. Il metodo ISourceBlock<TOutput>.LinkTo collega un blocco di origine del flusso di dati a un blocco di destinazione. Un'origine può essere collegato a zero o più destinazioni, le destinazioni possono essere collegati da zero o più database di origine. È possibile aggiungere o rimuovere i blocchi del flusso di dati o da una pipeline o una rete contemporaneamente. I tipi di blocchi predefiniti del flusso di dati gestire tutti gli aspetti di thread safety di accedere e disconnect.

Per un esempio che collega i blocchi del flusso di dati per formare una pipeline di base, vedere Procedura dettagliata: creazione di una pipeline del flusso di dati. Per un esempio che collega i blocchi del flusso di dati per formare una rete più complessa, vedere Procedura dettagliata: utilizzo del flusso di dati in un'applicazione Windows Form. Per un esempio che sconnette una destinazione da un'origine dopo che il database di origine offre al database di destinazione un messaggio, vedere Procedura: scollegare i blocchi di flussi di dati.

Hh228603.collapse_all(it-it,VS.110).gifFiltraggio

Quando si chiama il metodo ISourceBlock<TOutput>.LinkTo per collegare un database di origine a un database di destinazione, è possibile fornire un delegato che stabilisce se il blocco di destinazione deve accettare o rifiutare un messaggio in base al valore del messaggio. Questo processo di filtro garantiscono che un blocco del flusso di dati riceva solo determinati valori. Per la maggior parte dei tipi di blocchi predefiniti del flusso di dati, se un blocco di origine è connesso ai blocchi di destinazione multipli, quando un blocco di destinazione rifiutare un messaggio, le offerte di origine del messaggio alla destinazione seguente. L'ordine in cui un database di origine offre i messaggi a destinazioni è definito dal database di origine e può variare a seconda del tipo di origine. La maggior parte di interruzione di origine dei tipi di blocco che offre un messaggio dopo uno di destinazione accetta il messaggio. Un'eccezione a questa regola è la classe BroadcastBlock<T>, che offre ogni messaggio a tutti i database di destinazione, anche se alcuni target negare il messaggio. Per un esempio che utilizza il filtro per elaborare solo determinati messaggi, vedere Procedura dettagliata: utilizzo del flusso di dati in un'applicazione Windows Form.

Nota importante Importante

Poiché ogni tipo di blocco di origine predefinito del flusso di dati garantisce che i messaggi vengono propagati all'ordine in cui vengono ricevuti, ogni messaggio deve essere letta dal blocco di origine prima del blocco di origine può elaborare il messaggio successivo. Pertanto, quando si utilizza il filtro per connettere più destinazioni a un database di origine, accertarsi che almeno un blocco di destinazione ricevere ogni messaggio. In caso contrario, l'applicazione potrebbe verificarsi deadlock.

Hh228603.collapse_all(it-it,VS.110).gifPassaggio dei messaggi

Il modello di programmazione del flusso di dati è correlato al concetto di passaggio dei messaggi, in base al quale i componenti indipendenti di un programma comunicano con un altro programma inviando messaggi. Un modo per propagare i messaggi tra i componenti dell'applicazione consiste nel chiamare i metodi DataflowBlock.SendAsync e Post<TInput> per inviare messaggi al post di destinazione dei blocchi del flusso di dati (Post<TInput> agisce in modo sincrono, documenti SendAsync in modo asincrono) e Receive, ReceiveAsynce metodi TryReceive<TOutput> ricevere i messaggi dai blocchi di origine. È possibile combinare questi metodi con pipeline o reti del flusso di dati inviando i dati di input nel nodo head (un blocco di destinazione) e ricevendo i dati di input dal nodo terminale della pipeline o dei nodi finali di rete (uno o più dei blocchi). È inoltre possibile utilizzare il metodo Choose per leggere dal primo di origine forniti con dati disponibili e per eseguire l'operazione sui dati.

I dati originali offrono di blocchi per gestire i blocchi chiamando il metodo ITargetBlock<TInput>.OfferMessage. Il blocco di destinazione risponde a un messaggio offerto in tre modi: accetta il messaggio, il rifiuto del messaggio, o posticipare il messaggio. Quando la destinazione accetta il messaggio, il metodo OfferMessage restituisce Accepted. Quando la destinazione rifiuta il messaggio, il metodo OfferMessage restituisce Declined. Quando la destinazione richiede che non riceve i messaggi dal database di origine, in OfferMessage restituisce DecliningPermanently. I tipi di blocco di origine predefiniti non offrono i messaggi a destinazioni collegati dopo che questo valore restituito viene generato automaticamente sconnettono da tali destinazioni.

Quando un blocco di destinazione posticipare il messaggio per un utilizzo successivo, il metodo OfferMessage restituisce Postponed. Un blocco di destinazione che posticipa un messaggio può chiamate successive al metodo ISourceBlock<TOutput>.ReserveMessage provare a prenotare il messaggio offerto. In questa fase, il messaggio viene nuovamente o disponibile e può essere utilizzato dal blocco di destinazione, o il messaggio è stato creato da un altro database di destinazione. Quando il blocco di destinazione successiva richiede il messaggio o non necessita di messaggi, chiama il ISourceBlock<TOutput>.ConsumeMessage o il metodo ReleaseReservation, rispettivamente. La prenotazione dei messaggi in genere utilizzata dai tipi di blocco del flusso di dati che vengono eseguiti in modalità non-greedy. La modalità non-greedy viene illustrata più avanti in questo documento. Anziché riserva del messaggio posposto, un blocco di destinazione può inoltre utilizzare il metodo ISourceBlock<TOutput>.ConsumeMessage per tentare di utilizzare direttamente il messaggio posposto.

Hh228603.collapse_all(it-it,VS.110).gifCompletamento del blocco del flusso di dati

I blocchi del flusso di dati supportano il concetto di completamento. Un blocco del flusso di dati con stato completato non esegue alcuna per passare il lavoro. Ogni blocco del flusso di dati è un oggetto collegato System.Threading.Tasks.Task, noto come un'attività di completamento, che rappresenta lo stato di completamento del blocco. Poiché è possibile attendere che un oggetto Task per il completamento, tramite attività di completamento, è possibile attendere uno o più nodi finali di una rete del flusso di dati per completare. L'interfaccia IDataflowBlock definisce il metodo Complete, che informa il blocco del flusso di dati di una richiesta per completare e la proprietà Completion, che restituisce l'attività di completamento per il blocco del flusso di dati. Sia ISourceBlock<TOutput> che ereditano ITargetBlock<TInput> l'interfaccia IDataflowBlock.

Esistono due modi per determinare se un blocco del flusso di dati completato senza errori, rilevato uno o più errori, o annullati. La prima consiste nel chiamare il metodo Task.Wait l'attività di completamento in un blocco di try-catch (Try-Catch in Visual Basic). Nell'esempio seguente viene creato un oggetto ActionBlock<TInput> che genera ArgumentOutOfRangeException se il valore di input è minore di zero. AggregateException viene generato quando questo esempio viene chiamato Wait l'attività di completamento. ArgumentOutOfRangeException si accede mediante la proprietà InnerExceptions dell'oggetto AggregateException.


// Create an ActionBlock<int> object that prints its input
// and throws ArgumentOutOfRangeException if the input
// is less than zero.
var throwIfNegative = new ActionBlock<int>(n =>
{
   Console.WriteLine("n = {0}", n);
   if (n < 0)
   {
      throw new ArgumentOutOfRangeException();
   }
});

// Post values to the block.
throwIfNegative.Post(0);
throwIfNegative.Post(-1);
throwIfNegative.Post(1);
throwIfNegative.Post(-2);
throwIfNegative.Complete();

// Wait for completion in a try/catch block.
try
{
   throwIfNegative.Completion.Wait();
}
catch (AggregateException ae)
{
   // If an unhandled exception occurs during dataflow processing, all
   // exceptions are propagated through an AggregateException object.
   ae.Handle(e =>
   {
      Console.WriteLine("Encountered {0}: {1}", 
         e.GetType().Name, e.Message);
      return true;
   });
}

/* Output:
n = 0
n = -1
Encountered ArgumentOutOfRangeException: Specified argument was out of the range
 of valid values.
*/


In questo esempio viene illustrato il caso in cui un'eccezione non gestita viene inserito nel delegato di un blocco del flusso di esecuzione. È consigliabile gestire le eccezioni nei corpi di tali blocchi. Tuttavia, se non si riesce a tale scopo, il blocco si comporta come se fosse stato annullato e non elabora i messaggi in arrivo.

Quando un blocco del flusso di dati è impostato in modo esplicito, l'oggetto AggregateException contiene OperationCanceledException nella proprietà InnerExceptions. Per ulteriori informazioni sull'annullamento del flusso di dati, vedere abilitare l'annullamento più avanti in questo documento.

La seconda modalità per determinare lo stato di completamento di un blocco del flusso di dati è utilizzare una continuazione dell'attività di completamento, o utilizzare le funzionalità del linguaggio asincrone di Visual Basic e C# in modo asincrono per attendere l'attività di completamento. Il delegato che fornite all'Task.ContinueWith il metodo accetta un oggetto Task che rappresenta l'attività precedente. Nel caso della proprietà Completion, il delegato per la continuazione esegue l'attività di completamento stessa. L'esempio seguente è simile al precedente, con la differenza che utilizza il metodo ContinueWith per creare un'attività di completamento che visualizza lo stato dell'operazione globale del flusso di dati.


// Create an ActionBlock<int> object that prints its input
// and throws ArgumentOutOfRangeException if the input
// is less than zero.
var throwIfNegative = new ActionBlock<int>(n =>
{
   Console.WriteLine("n = {0}", n);
   if (n < 0)
   {
      throw new ArgumentOutOfRangeException();
   }
});

// Create a continuation task that prints the overall 
// task status to the console when the block finishes.
throwIfNegative.Completion.ContinueWith(task =>
{
   Console.WriteLine("The status of the completion task is '{0}'.", 
      task.Status);
});

// Post values to the block.
throwIfNegative.Post(0);
throwIfNegative.Post(-1);
throwIfNegative.Post(1);
throwIfNegative.Post(-2);
throwIfNegative.Complete();

// Wait for completion in a try/catch block.
try
{
   throwIfNegative.Completion.Wait();
}
catch (AggregateException ae)
{
   // If an unhandled exception occurs during dataflow processing, all
   // exceptions are propagated through an AggregateException object.
   ae.Handle(e =>
   {
      Console.WriteLine("Encountered {0}: {1}",
         e.GetType().Name, e.Message);
      return true;
   });
}

/* Output:
n = 0
n = -1
The status of the completion task is 'Faulted'.
Encountered ArgumentOutOfRangeException: Specified argument was out of the range
 of valid values.
*/


È possibile utilizzare le proprietà come IsCanceled nel corpo dell'attività di continuazione ottenere informazioni aggiuntive sullo stato di completamento di un blocco del flusso di dati. Per ulteriori informazioni sulle attività di continuazione e la rispettiva per l'annullamento e la gestione degli errori, vedere Attività di continuazionesu, su Annullamento delle attività, in Gestione delle eccezioni (Task Parallel Library)e su Procedura: gestire le eccezioni generate dalle attività.

[vai all'inizio]

La raccolta di flusso di libreria TPL fornisce vari tipi di blocchi predefiniti del flusso di dati. Questi tipi sono suddivisi in tre categorie: blocchi di buffer, blocchi di esecuzionee raggruppare i blocchi. Nelle sezioni seguenti vengono descritti i tipi di blocco che compongono queste categorie.

Hh228603.collapse_all(it-it,VS.110).gifBlocchi di buffer

Dati al fine dei blocchi di buffer con gli utenti di dati. La raccolta di flusso di libreria TPL fornisce tre tipi di blocco memorizzazione nel buffer: System.Threading.Tasks.Dataflow.BufferBlock<T>, System.Threading.Tasks.Dataflow.BroadcastBlock<T>e System.Threading.Tasks.Dataflow.WriteOnceBlock<T>.

Hh228603.collapse_all(it-it,VS.110).gifBufferBlock (T)

La classe BufferBlock<T> rappresenta una struttura di messaggistica asincrona di utilizzo generale. Questa classe archivia una coda di messaggi FIFO (First In, First Out) che possono essere letti da più destinazioni o in cui possono scrivere più origini. Quando una destinazione riceve un messaggio da un oggetto BufferBlock<T>, il messaggio viene rimosso dalla coda di messaggi. Pertanto, sebbene un oggetto BufferBlock<T> possa avere più destinazioni, solo una destinazione riceve ogni messaggio. La classe BufferBlock<T> è utile quando si desidera passare più messaggi a un altro componente e tale componente deve ricevere ogni messaggio.

Nell'esempio di base in diversi valori Int32 a un oggetto BufferBlock<T> quindi legge i valori indietro di tale oggetto.


// Create a BufferBlock<int> object.
var bufferBlock = new BufferBlock<int>();

// Post several messages to the block.
for (int i = 0; i < 3; i++)
{
   bufferBlock.Post(i);
}

// Receive the messages back from the block.
for (int i = 0; i < 3; i++)
{
   Console.WriteLine(bufferBlock.Receive());
}

/* Output:
   0
   1
   2
 */


Per un esempio completo in cui viene illustrato come scrivere i messaggi e leggere i messaggi da BufferBlock<T> oggetto, vedere Procedura: scrivere messaggi in un blocco di flussi di dati e leggere messaggi da un blocco di flussi di dati.

Hh228603.collapse_all(it-it,VS.110).gifBroadcastBlock (T)

La classe BroadcastBlock<T> è necessario, ma il componente più messaggi a un altro componente necessario passare utili quando solo il valore più recente. Questa classe è utile anche quando si desidera trasmettere un messaggio a più componenti.

Nell'esempio di base inserisce un valore Double a un oggetto BroadcastBlock<T> quindi legge il valore di da tale oggetto più volte. Poiché i valori non vengono rimossi da BroadcastBlock<T> oggetti dopo che vengono letti, lo stesso valore quando è disponibile.


// Create a BroadcastBlock<double> object.
var broadcastBlock = new BroadcastBlock<double>(null);

// Post a message to the block.
broadcastBlock.Post(Math.PI);

// Receive the messages back from the block several times.
for (int i = 0; i < 3; i++)
{
   Console.WriteLine(broadcastBlock.Receive());
}

/* Output:
   3.14159265358979
   3.14159265358979
   3.14159265358979
 */


Per un esempio completo che illustra come utilizzare BroadcastBlock<T> per trasmettere per comunicare un messaggio ai blocchi di destinazione multipli, vedere Procedura: specificare un'utilità di pianificazione in un blocco di flussi di dati.

Hh228603.collapse_all(it-it,VS.110).gifWriteOnceBlock (T)

La classe WriteOnceBlock<T> è simile alla classe BroadcastBlock<T>, ma un oggetto WriteOnceBlock<T> è possibile scrivere una sola volta. È possibile pensare a WriteOnceBlock<T> come è simile alla parola chiave di C# in sola lettura (In sola lettura in Visual Basic), ma un oggetto WriteOnceBlock<T> diventa non modificabile dopo che riceve un valore anziché costruzione. Analogamente alla classe BroadcastBlock<T>, quando una destinazione riceve un messaggio da un oggetto WriteOnceBlock<T>, il messaggio non viene rimosso dall'oggetto. Pertanto, una copia del messaggio viene ricevuta da più destinazioni. La classe WriteOnceBlock<T> è utile quando si desidera propagare solo il primo dei messaggi.

Più valori String dei post di esempio base a WriteOnceBlock<T> oggetto e quindi legge il valore di da tale oggetto. Poiché un oggetto WriteOnceBlock<T> è possibile scrivere una sola volta, dopo un oggetto WriteOnceBlock<T> riceve un messaggio, rimuove i messaggi successivi.


// Create a WriteOnceBlock<string> object.
var writeOnceBlock = new WriteOnceBlock<string>(null);

// Post several messages to the block in parallel. The first 
// message to be received is written to the block. 
// Subsequent messages are discarded.
Parallel.Invoke(
   () => writeOnceBlock.Post("Message 1"),
   () => writeOnceBlock.Post("Message 2"),
   () => writeOnceBlock.Post("Message 3"));

// Receive the message from the block.
Console.WriteLine(writeOnceBlock.Receive());

/* Sample output:
   Message 2
 */


Per un esempio completo che illustra come utilizzare WriteOnceBlock<T> per ricevere il valore della prima operazione che il termine, vedere a Procedura: scollegare i blocchi di flussi di dati.

Hh228603.collapse_all(it-it,VS.110).gifBlocchi di esecuzione

I blocchi di esecuzione chiamano forniti dall'utente il delegato di ogni porzione di dati ricevuti. La raccolta di flusso di libreria TPL fornisce tre tipi di blocco di esecuzione: ActionBlock<TInput>, System.Threading.Tasks.Dataflow.TransformBlock<TInput, TOutput>e System.Threading.Tasks.Dataflow.TransformManyBlock<TInput, TOutput>.

Hh228603.collapse_all(it-it,VS.110).gifActionBlock (T)

La classe ActionBlock<TInput> è un blocco di destinazione che chiama un delegato quando riceve i dati. Considerare un oggetto ActionBlock<TInput> come delegato che funziona in modo asincrono quando i dati diventano disponibili. Il delegato fornito a ActionBlock<TInput> un oggetto può essere di tipo Action o digitare System.Func<TInput, Task>. Quando si utilizza un oggetto ActionBlock<TInput> con Action, l'elaborazione di ogni elemento di input viene considerato completato al completamento del delegato. Quando si utilizza un oggetto ActionBlock<TInput> con System.Func<TInput, Task>, l'elaborazione di ogni elemento di input viene considerato completato solo quando l'oggetto restituito Task viene completato. Tramite questi due meccanismi, è possibile utilizzare ActionBlock<TInput> sia sincrono che l'elaborazione asincrona di ogni elemento di input.

Più valori Int32 dei post di esempio base a ActionBlock<TInput> oggetto. L'oggetto ActionBlock<TInput> stampa tali valori nella console. Viene quindi impostato il blocco lo stato completato e attende che tutte le attività del flusso di dati completare.


// Create an ActionBlock<int> object that prints values
// to the console.
var actionBlock = new ActionBlock<int>(n => Console.WriteLine(n));

// Post several messages to the block.
for (int i = 0; i < 3; i++)
{
   actionBlock.Post(i * 10);
}

// Set the block to the completed state and wait for all 
// tasks to finish.
actionBlock.Complete();
actionBlock.Completion.Wait();

/* Output:
   0
   10
   20
 */


Per esempi completi che illustrano come utilizzare i delegati con ActionBlock<TInput> classe, vedere Procedura: eseguire un'azione alla ricezione di dati in un blocco di flussi di dati.

Hh228603.collapse_all(it-it,VS.110).gifTransformBlock (TInput, TOutput)

La classe TransformBlock<TInput, TOutput> è simile alla classe ActionBlock<TInput>, con la differenza che funge sia dalle origini che come destinazione. Il delegato passato a TransformBlock<TInput, TOutput> a un oggetto restituisce un valore di tipo TOutput. Il delegato fornito a TransformBlock<TInput, TOutput> un oggetto può essere di tipo System.Func<TInput, TOutput> o digitare System.Func<TInput, Task>. Quando si utilizza un oggetto TransformBlock<TInput, TOutput> con System.Func<TInput, TOutput>, l'elaborazione di ogni elemento di input viene considerato completato al completamento del delegato. Quando si utilizza un oggetto TransformBlock<TInput, TOutput> utilizzato con System.Func<TInput, Task<TOutput>>, l'elaborazione di ogni elemento di input viene considerato completato solo quando l'oggetto restituito Task viene completato. Come con ActionBlock<TInput>, utilizzando questi due meccanismi, è possibile utilizzare TransformBlock<TInput, TOutput> sia sincrono che l'elaborazione asincrona di ogni elemento di input.

Nell'esempio di base crea un oggetto TransformBlock<TInput, TOutput> che calcola la radice quadrata dell'input. L'oggetto TransformBlock<TInput, TOutput> accetta valori Int32 pertanto introdotti e produce valori Double quanto restituisce.


// Create a TransformBlock<int, double> object that 
// computes the square root of its input.
var transformBlock = new TransformBlock<int, double>(n => Math.Sqrt(n));

// Post several messages to the block.
transformBlock.Post(10);
transformBlock.Post(20);
transformBlock.Post(30);

// Read the output messages from the block.
for (int i = 0; i < 3; i++)
{
   Console.WriteLine(transformBlock.Receive());
}

/* Output:
   3.16227766016838
   4.47213595499958
   5.47722557505166
 */


Per esempi completi che utilizza TransformBlock<TInput, TOutput> in una rete di blocchi del flusso di dati che esegue l'elaborazione di immagini in un'applicazione Windows Form, vedere Procedura dettagliata: utilizzo del flusso di dati in un'applicazione Windows Form.

Hh228603.collapse_all(it-it,VS.110).gifTransformManyBlock (TInput, TOutput)

La classe TransformManyBlock<TInput, TOutput> è simile alla classe TransformBlock<TInput, TOutput>, ma TransformManyBlock<TInput, TOutput> produce zero o più valori di output per ogni valore di input, anziché solo un valore di output per ogni valore di input. Il delegato fornito a TransformManyBlock<TInput, TOutput> un oggetto può essere di tipo System.Func<TInput, IEnumerable<TOutput>> o type System.Func<TInput, Task<IEnumerable<TOutput>>>. Quando si utilizza un oggetto TransformManyBlock<TInput, TOutput> con System.Func<TInput, IEnumerable<TOutput>>, l'elaborazione di ogni elemento di input viene considerato completato al completamento del delegato. Quando si utilizza un oggetto TransformManyBlock<TInput, TOutput> con System.Func<TInput, Task<IEnumerable<TOutput>>>, l'elaborazione di ogni elemento di input viene considerato completo solo quando l'oggetto restituito System.Threading.Tasks.Task<IEnumerable<TOutput>> viene completato.

Nell'esempio di base crea un oggetto TransformManyBlock<TInput, TOutput> che suddivide le stringhe nelle sequenze di carattere. L'oggetto TransformManyBlock<TInput, TOutput> accetta valori String pertanto introdotti e produce valori Char quanto restituisce.


// Create a TransformManyBlock<string, char> object that splits
// a string into its individual characters.
var transformManyBlock = new TransformManyBlock<string, char>(
   s => s.ToCharArray());

// Post two messages to the first block.
transformManyBlock.Post("Hello");
transformManyBlock.Post("World");

// Receive all output values from the block.
for (int i = 0; i < ("Hello" + "World").Length; i++)
{
   Console.WriteLine(transformManyBlock.Receive());
}

/* Output:
   H
   e
   l
   l
   o
   W
   o
   r
   l
   d
 */


Per esempi completi che utilizzano TransformManyBlock<TInput, TOutput> per produrre output indipendenti più per ogni input in un flusso canalizzano, vedere Procedura dettagliata: creazione di una pipeline del flusso di dati.

Hh228603.collapse_all(it-it,VS.110).gifLivello di parallelismo

Ogni ActionBlock<TInput>, TransformBlock<TInput, TOutput>e i buffer dell'oggetto TransformManyBlock<TInput, TOutput> illustrati i messaggi finché il blocco non sia pronto per elaborarli. Per impostazione predefinita, questi i messaggi di classi nell'ordine in cui vengono ricevuti, un messaggio per volta. È inoltre possibile specificare il grado di parallelismo per consentire a ActionBlock<TInput>, a TransformBlock<TInput, TOutput> e agli oggetti TransformManyBlock<TInput, TOutput> per elaborare i messaggi contemporaneamente più. Per ulteriori informazioni sull'esecuzione simultanea, vedere la sezione specifica il grado di parallelismo più avanti in questo documento. Per un esempio che imposta il grado di parallelismo per consentire a un blocco del flusso di esecuzione per elaborare più messaggi contemporaneamente, vedere Procedura: specificare il grado di parallelismo in un blocco di flussi di dati.

Hh228603.collapse_all(it-it,VS.110).gifRiepilogo dei tipi delegati

Nella tabella seguente vengono riepilogati i tipi delegati che è possibile fornire a ActionBlock<TInput>, a TransformBlock<TInput, TOutput>e agli oggetti TransformManyBlock<TInput, TOutput>. Questa tabella specifica anche se il tipo delegato viene eseguita in modo sincrono o asincrono.

Tipo

Tipo delegato sincrono

Tipo delegato asincrono

ActionBlock<TInput>

System.Action

System.Func<TInput, Task>

TransformBlock<TInput, TOutput>

System.Func<TInput, TOutput>`2

System.Func<TInput, Task<TOutput>>

TransformManyBlock<TInput, TOutput>

System.Func<TInput, IEnumerable<TOutput>>

System.Func<TInput, Task<IEnumerable<TOutput>>>

È inoltre possibile utilizzare le espressioni lambda quando si utilizzano tipi di blocco di esecuzione. Per un esempio che illustra come utilizzare un'espressione lambda con un blocco di esecuzione, vedere Procedura: eseguire un'azione alla ricezione di dati in un blocco di flussi di dati.

Hh228603.collapse_all(it-it,VS.110).gifBlocchi di raggruppamento

I blocchi di raggruppamento combinano i dati da uno o più database di origine e in vari vincoli. La raccolta di flusso di libreria TPL fornisce tre tipi di blocco di join: BatchBlock<T>, JoinBlock<T1, T2>e BatchedJoinBlock<T1, T2>.

Hh228603.collapse_all(it-it,VS.110).gifBatchBlock (T)

La classe BatchBlock<T> combina i set di dati di input, noti come batch, le matrici di dati di output. Specificare la dimensione di ciascun batch quando si crea un oggetto BatchBlock<T>. Quando l'oggetto BatchBlock<T> riceve il numero specificato di elementi di input, in modo asincrono propaga a una matrice contenente gli elementi. Se un oggetto BatchBlock<T> è impostato lo stato completato ma non contiene elementi sufficiente per formare un batch, propaga a una matrice finale contenente gli elementi di input rimanenti.

La classe BatchBlock<T> viene eseguito in modalità greedy e non-greedy. In modalità generici, ovvero l'impostazione predefinita, un oggetto BatchBlock<T> accetta ogni messaggio che venga fornito e propagazioni a una matrice dopo che riceve il numero specificato di elementi. In modalità specifica, un oggetto BatchBlock<T> posticipa tutti i messaggi in arrivo finché il database di origine non ha fornito messaggi al blocco per formare un batch. La modalità greedy generalmente eseguita la modalità più adatta non-greedy poiché richiede meno sovraccarico di elaborazione. Tuttavia, è possibile utilizzare la modalità non-greedy quando è necessario coordinare l'utilizzo di origini in modo atomico. Specificare la modalità specifica impostando Greedy a False nel parametro dataflowBlockOptions nel costruttore BatchBlock<T>.

Nell'esempio di base in diversi valori Int32 a un oggetto BatchBlock<T> che utilizza dieci elementi in batch. Per garantire che tutti i valori si passano da BatchBlock<T>, chiamate di questo esempio il metodo Complete. Il metodo Complete imposta l'oggetto BatchBlock<T> lo stato completato e pertanto, le propagazioni dell'oggetto BatchBlock<T> tutti gli elementi rimanenti come batch finale.


// Create a BatchBlock<int> object that holds ten
// elements per batch.
var batchBlock = new BatchBlock<int>(10);

// Post several values to the block.
for (int i = 0; i < 13; i++)
{
   batchBlock.Post(i);
}
// Set the block to the completed state. This causes
// the block to propagate out any any remaining
// values as a final batch.
batchBlock.Complete();

// Print the sum of both batches.

Console.WriteLine("The sum of the elements in batch 1 is {0}.",
   batchBlock.Receive().Sum());

Console.WriteLine("The sum of the elements in batch 2 is {0}.",
   batchBlock.Receive().Sum());

/* Output:
   The sum of the elements in batch 1 is 45.
   The sum of the elements in batch 2 is 33.
 */


Per un esempio completo che utilizza BatchBlock<T> per migliorare l'efficienza delle operazioni di inserimento del database, vedere Procedura dettagliata: utilizzo di BatchBlock e BatchedJoinBlock per migliorare l'efficienza.

Hh228603.collapse_all(it-it,VS.110).gifJoinBlock (T1,T2,…)

Le classi JoinBlock<T1, T2, T3> e JoinBlock<T1, T2> raccolgono gli elementi di input e propaga a System.Tuple<T1, T2> o oggetti System.Tuple<T1, T2, T3> che contengono gli elementi. Le classi JoinBlock<T1, T2, T3> e JoinBlock<T1, T2> non ereditano da ITargetBlock<TInput>. Invece, forniscono proprietà, Target1, Target2e Target3, che implementano ITargetBlock<TInput>.

Come BatchBlock<T>, JoinBlock<T1, T2> e JoinBlock<T1, T2, T3> esecuzione in modalità greedy e non-greedy. In modalità generici, ovvero l'impostazione predefinita, un oggetto JoinBlock<T1, T2, T3> o JoinBlock<T1, T2> accetta ogni messaggio che venga fornito e propagazioni a una tupla dopo ciascuna delle relative destinazioni riceve almeno un messaggio. In modalità specifica, un oggetto JoinBlock<T1, T2, T3> o JoinBlock<T1, T2> posticipa tutti i messaggi in arrivo finché offrire tutte le destinazioni i dati richiesti per creare una tupla. In questa fase, il blocco si impegna in un protocollo in due fasi di commit atomico per recuperare tutti gli elementi richiesti da origini. Il rinvio consente a un'altra entità utilizzare contemporaneamente i dati, per consentire al sistema complessivo eseguire i progressi avanti.

Nell'esempio di base seguente viene illustrato un caso in cui un oggetto JoinBlock<T1, T2, T3> richiede dati più di calcolare un valore. In questo esempio viene creato un oggetto JoinBlock<T1, T2, T3> che richiede due valori Int32 e un valore Char di eseguire un'operazione aritmetica.


// Create a JoinBlock<int, int, char> object that requires
// two numbers and an operator.
var joinBlock = new JoinBlock<int, int, char>();

// Post two values to each target of the join.

joinBlock.Target1.Post(3);
joinBlock.Target1.Post(6);

joinBlock.Target2.Post(5);
joinBlock.Target2.Post(4);

joinBlock.Target3.Post('+');
joinBlock.Target3.Post('-');

// Receive each group of values and apply the operator part
// to the number parts.

for (int i = 0; i < 2; i++)
{
   var data = joinBlock.Receive();
   switch (data.Item3)
   {
      case '+':
         Console.WriteLine("{0} + {1} = {2}",
            data.Item1, data.Item2, data.Item1 + data.Item2);
         break;
      case '-':
         Console.WriteLine("{0} - {1} = {2}",
            data.Item1, data.Item2, data.Item1 - data.Item2);
         break;
      default:
         Console.WriteLine("Unknown operator '{0}'.", data.Item3);
         break;
   }
}

/* Output:
   3 + 5 = 8
   6 - 4 = 2
 */


Per un esempio completo che utilizza oggetti JoinBlock<T1, T2> in modalità non-greedy in modo cooperativo per condividere una risorsa, vedere Procedura: utilizzare JoinBlock per leggere dati da più origini.

Hh228603.collapse_all(it-it,VS.110).gifBatchedJoinBlock (T1,T2,…)

Le classi BatchedJoinBlock<T1, T2, T3> e BatchedJoinBlock<T1, T2> raccolgono le serie di elementi di input e propaga a System.Tuple(IList(T1), IList(T2)) o oggetti System.Tuple(IList(T1), IList(T2), IList(T3)) che contengono gli elementi. Pensare a BatchedJoinBlock<T1, T2> come combinazione BatchBlock<T> e JoinBlock<T1, T2>. Specificare la dimensione di ciascun batch quando si crea un oggetto BatchedJoinBlock<T1, T2>. BatchedJoinBlock<T1, T2> fornisce inoltre le proprietà, Target1 e Target2, che implementano ITargetBlock<TInput>. Quando il numero specificato di elementi di input viene ricevuto dall'altro lato di tutti i database di destinazione, l'oggetto BatchedJoinBlock<T1, T2> in modo asincrono propaga a un oggetto System.Tuple(IList(T1), IList(T2)) contenente tali elementi.

Nell'esempio di base crea un oggetto BatchedJoinBlock<T1, T2> che utilizza i risultati, i valori Int32 ed errori che sono oggetti Exception. In questo esempio vengono eseguite più operazioni e scrive i risultati alla proprietà Target1 ed errori alla proprietà Target2, l'oggetto BatchedJoinBlock<T1, T2>. Poiché il conteggio di riuscita e operazioni non riuscite è in anticipo sconosciuto, gli oggetti IList<T> consentono a ogni target per ricevere zero o più valori.


// Create a JoinBlock<int, int, char> object that requires
// two numbers and an operator.
var joinBlock = new JoinBlock<int, int, char>();

// Post two values to each target of the join.

joinBlock.Target1.Post(3);
joinBlock.Target1.Post(6);

joinBlock.Target2.Post(5);
joinBlock.Target2.Post(4);

joinBlock.Target3.Post('+');
joinBlock.Target3.Post('-');

// Receive each group of values and apply the operator part
// to the number parts.

for (int i = 0; i < 2; i++)
{
   var data = joinBlock.Receive();
   switch (data.Item3)
   {
      case '+':
         Console.WriteLine("{0} + {1} = {2}",
            data.Item1, data.Item2, data.Item1 + data.Item2);
         break;
      case '-':
         Console.WriteLine("{0} - {1} = {2}",
            data.Item1, data.Item2, data.Item1 - data.Item2);
         break;
      default:
         Console.WriteLine("Unknown operator '{0}'.", data.Item3);
         break;
   }
}

/* Output:
   3 + 5 = 8
   6 - 4 = 2
 */


Per un esempio completo che utilizza BatchedJoinBlock<T1, T2> per acquisire i risultati e tutte le eccezioni che si verificano durante l'esecuzione del programma viene letto da un database, vedere Procedura dettagliata: utilizzo di BatchBlock e BatchedJoinBlock per migliorare l'efficienza.

[vai all'inizio]

È possibile abilitare le opzioni aggiuntive fornendo un oggetto System.Threading.Tasks.Dataflow.DataflowBlockOptions al costruttore dei tipi di blocco del flusso di dati. Comportamento di controllo di queste opzioni tali l'utilità di pianificazione che gestisce l'attività sottostante e il grado di parallelismo. DataflowBlockOptions dispone anche di tipi derivati che specificano il comportamento specifico per determinati tipi di blocco del flusso di dati. Nella tabella seguente viene riepilogato il tipo di opzioni è associato a ogni tipo di blocco del flusso di dati.

Nelle sezioni seguenti vengono fornite informazioni aggiuntive sui principali tipi di opzioni di blocco del flusso di dati disponibili in System.Threading.Tasks.Dataflow.DataflowBlockOptions, System.Threading.Tasks.Dataflow.ExecutionDataflowBlockOptionse le classi System.Threading.Tasks.Dataflow.GroupingDataflowBlockOptions.

Hh228603.collapse_all(it-it,VS.110).gifSpecificare l'utilità di pianificazione

Ogni blocco predefinito del flusso di dati utilizzato il meccanismo di pianificazione delle attività di libreria TPL per eseguire attività quali la propagazione dei dati in un database di destinazione, la ricezione di dati da un'origine ed eseguire i delegati definiti dall'utente quando i dati diventano disponibili. TaskScheduler è una classe astratta che rappresenta un'utilità di pianificazione che mette in coda le attività dei thread. L'utilità di pianificazione predefinita, Default, utilizzare la classe ThreadPool accodare ed eseguire lavoro. È possibile eseguire l'override dell'utilità di pianificazione predefinita impostando la proprietà TaskScheduler quando si costruisce un oggetto del blocco del flusso di dati.

Quando la stessa utilità di pianificazione gestisce i più blocchi del flusso di dati, è possibile applicare i criteri relativi. Ad esempio, se si blocca in ciascuno del flusso di dati configurati per utilizzare l'utilità di pianificazione determina lo stesso oggetto ConcurrentExclusiveSchedulerPair, tutto il lavoro eseguito tramite questi blocchi è serializzata. Analogamente, se questi blocchi sono configurati per utilizzare l'utilità di pianificazione simultanee lo stesso oggetto ConcurrentExclusiveSchedulerPair e l'utilità di pianificazione è configurato per avere un livello di concorrenza massimo, tutto il lavoro da questi blocchi è limitato al numero di operazioni simultanee. Per un esempio che utilizza la classe ConcurrentExclusiveSchedulerPair per abilitare le operazioni di lettura per essere eseguite in parallelo, ma le operazioni di scrittura per verificare separatamente di tutte le altre operazioni, vedere Procedura: specificare un'utilità di pianificazione in un blocco di flussi di dati. Per ulteriori informazioni sulle utilità di pianificazione in TPL, inclusa la classe ConcurrentExclusiveSchedulerPair, vedere Utilità di pianificazione delle attività.

Hh228603.collapse_all(it-it,VS.110).gifSpecificare il grado di parallelismo

Per impostazione predefinita, i tre tipi di blocco che la raccolta di flusso di libreria TPL modo, ActionBlock<TInput>, TransformBlock<TInput, TOutput>e TransformManyBlock<TInput, TOutput>di esecuzione, elaborare un messaggio per volta. Questi del flusso dei tipi di blocco dei messaggi anche nell'ordine in cui vengono ricevuti. Per consentire a questi blocchi del flusso di dati per elaborare i messaggi contemporaneamente, impostare la proprietà ExecutionDataflowBlockOptions.MaxDegreeOfParallelism quando si crea l'oggetto del blocco del flusso di dati.

Il valore predefinito MaxDegreeOfParallelism è 1, che garantisce che il blocco del flusso di dati elabora un messaggio per volta. Impostare questa proprietà su un valore maggiore di 1 consente al blocco del flusso di dati per elaborare i messaggi contemporaneamente più. Impostare la proprietà su DataflowBlockOptions.Unbounded consente all'utilità di pianificazione sottostante per gestire il livello massimo di concorrenza.

Nota importante Importante

Quando si specifica un livello massimo di parallelismo maggiore di 1, più messaggi vengono elaborati contemporaneamente, pertanto i messaggi potrebbero non essere elaborati in ordine in cui vengono ricevuti. L'ordine in cui i messaggi vengono restituiti dal blocco, tuttavia, correttamente verrà ordinato.

Poiché la proprietà MaxDegreeOfParallelism rappresenta il livello massimo di parallelismo, il blocco del flusso di dati può eseguire con un massimo grado di parallelismo specificato. Il blocco del flusso di dati può contenere un massimo grado di parallelismo per soddisfare le richieste funzionali o perché è una mancanza di risorse di sistema disponibili. Un blocco del flusso di dati non può mai più parallelismo specificato.

Il valore della proprietà MaxDegreeOfParallelism è esclusivo a ogni oggetto del blocco del flusso di dati. Ad esempio, se quattro blocchi di flusso oggetto ognuno specificare 1 per il massimo grado di parallelismo, tutti e quattro gli oggetti del blocco del flusso di dati potenzialmente può essere eseguito in parallelo.

Per un esempio che imposta il massimo grado di parallelismo per abilitare le operazioni lunghe per verificare in parallelo, vedere Procedura: specificare il grado di parallelismo in un blocco di flussi di dati.

Hh228603.collapse_all(it-it,VS.110).gifSpecificare il numero di messaggi per attività

I tipi di blocchi predefiniti del flusso di dati utilizzano le attività elaborare gli elementi di input. Ciò contribuisce a ridurre il numero di oggetti task necessari per elaborare i dati, che consentono alle applicazioni eseguite in modo più efficiente. Tuttavia, quando le attività da un set di blocchi del flusso di dati a elaborare i dati, attività da altri blocchi del flusso di dati potrebbero essere necessario attendere il tempo di elaborazione accodamento messaggi. Per abilitare la migliore equità tra attività del flusso di dati, impostare la proprietà MaxMessagesPerTask. Quando MaxMessagesPerTask è impostato su DataflowBlockOptions.Unbounded, ovvero l'impostazione predefinita, l'attività utilizzata da un blocco del flusso di dati elabora tutti i messaggi come sono disponibili. Quando MaxMessagesPerTask è impostato su un valore diverso da Unbounded, i processi del blocco del flusso di dati al massimo questo numero di messaggi per l'oggetto Task. Sebbene impostare la proprietà MaxMessagesPerTask può aumentare l'equità tra le attività, può provocare il sistema per creare più attività, che possono ridurre le prestazioni.

Hh228603.collapse_all(it-it,VS.110).gifAbilitare l'annullamento

La libreria TPL fornisce un meccanismo che consente alle attività coordinare l'annullamento in modo cooperativo. Per consentire ai blocchi del flusso di dati per partecipare a questo meccanismo di annullamento, impostare la proprietà CancellationToken. Quando l'oggetto CancellationToken è impostato sullo stato annullato, tutti i blocchi del flusso di dati che controllano l'esecuzione del token di inizio dell'elemento corrente ma non iniziano elaborare gli elementi successivi. Questi blocchi del flusso di dati anche possibile definire i messaggi memorizzati nel buffer, connessioni della versione ai blocchi di origine e di destinazione e transizione allo stato canceled. La transizione allo stato canceled, la proprietà Completion è stata impostata la proprietà Status a Canceled, a meno che l'eccezione venga eseguita durante l'elaborazione. In tal caso, Status è impostato su Faulted.

Per un esempio che illustra come utilizzare l'annullamento in un'applicazione Windows Form, vedere Procedura: annullare un blocco di flussi di dati. Per ulteriori informazioni sull'annullamento nella libreria TPL, vedere Annullamento delle attività.

Hh228603.collapse_all(it-it,VS.110).gifSpecificare greedy e non-greedy comportamento

Diversi che raggruppano i tipi di blocco del flusso di dati possono essere eseguite in modalità greedy e non-greedy. Per impostazione predefinita, i tipi di blocchi predefiniti del flusso di dati vengono eseguiti in modalità greedy.

Per i tipi di blocco di join come JoinBlock<T1, T2>, la modalità greedy significa che il blocco immediatamente accetta i dati anche se i dati corrispondenti a cui aggiungere non è ancora disponibile. La modalità non-greedy significa che il blocco posticipa tutti i messaggi in arrivo finché non ne sia disponibile in ciascuna delle relative destinazioni per completare l'operazione di join. Se uno dei messaggi posposti non sono più disponibili, il blocco di join pubblica tutti i messaggi posposti e riavviare il processo. Per la classe BatchBlock<T>, il comportamento di non-greedy e di greedy è simile, tranne che nella modalità specifica, un oggetto BatchBlock<T> posticipa tutti i messaggi in arrivo finché sufficiente non sono disponibili da origine distinti per completare un batch.

Per specificare la modalità non-greedy per un blocco del flusso di dati, impostare Greedy a False. Per un esempio che illustra come utilizzare la modalità non-greedy per consentire a più blocchi di join per condividere più efficiente un'origine dati, vedere Procedura: utilizzare JoinBlock per leggere dati da più origini.

[vai all'inizio]

Sebbene la raccolta di flusso di libreria TPL fornisce molti tipi di blocchi predefiniti, è possibile creare tipi di blocco aggiuntivi che eseguono il comportamento personalizzato. Implementare direttamente le interfacce ITargetBlock<TInput> o ISourceBlock<TOutput> o utilizzare il metodo Encapsulate<TInput, TOutput> per compilare un blocco complesso che incapsula il comportamento dei tipi di blocco esistenti. Per esempi che illustrano come implementare funzionalità personalizzate del blocco del flusso di dati, vedere Procedura dettagliata: creazione di un tipo di blocco di flussi di dati personalizzato.

[vai all'inizio]

Titolo

Descrizione

Procedura: scrivere messaggi in un blocco di flussi di dati e leggere messaggi da un blocco di flussi di dati

Viene illustrato come per scrivere e leggere i messaggi da un oggetto BufferBlock<T>.

Procedura: implementare un modello di flusso di dati producer-consumer

Viene descritto come utilizzare il modello di flusso di dati per applicare un modello producer-consumer, in cui il producer invia messaggi a un blocco del flusso di dati e il consumer legge i messaggi da tale blocco.

Procedura: eseguire un'azione alla ricezione di dati in un blocco di flussi di dati

Viene descritto come fornire ai delegati ai tipi di blocco, a ActionBlock<TInput>, a TransformBlock<TInput, TOutput>e a TransformManyBlock<TInput, TOutput>del flusso di esecuzione.

Procedura dettagliata: creazione di una pipeline del flusso di dati

Viene descritto come creare una pipeline del flusso di dati che scarica il testo dal web ed esegue le operazioni nel testo.

Procedura: scollegare i blocchi di flussi di dati

Viene illustrato come utilizzare il metodo LinkTo per scollegare un blocco di destinazione dal database di origine dopo che il database di origine offre un messaggio alla destinazione.

Procedura dettagliata: utilizzo del flusso di dati in un'applicazione Windows Form

Viene illustrato come creare una rete di blocchi del flusso di dati che eseguono l'elaborazione di immagini in un'applicazione Windows Form.

Procedura: annullare un blocco di flussi di dati

Viene illustrato come utilizzare l'annullamento in un'applicazione Windows Form.

Procedura: utilizzare JoinBlock per leggere dati da più origini

Viene illustrato come utilizzare la classe JoinBlock<T1, T2> per eseguire un'operazione quando i dati sono disponibili da più database di origine e come utilizzare la modalità non-greedy per consentire a più blocchi di join per condividere più efficiente un'origine dati.

Procedura: specificare il grado di parallelismo in un blocco di flussi di dati

Viene descritto come impostare la proprietà MaxDegreeOfParallelism per consentire a un blocco del flusso di esecuzione per elaborare più messaggi per volta.

Procedura: specificare un'utilità di pianificazione in un blocco di flussi di dati

Viene illustrato come associare un'utilità di pianificazione specifica quando si utilizza il flusso nell'applicazione.

Procedura dettagliata: utilizzo di BatchBlock e BatchedJoinBlock per migliorare l'efficienza

Viene descritto come utilizzare la classe BatchBlock<T> per migliorare l'efficienza delle operazioni di inserimento del database e come utilizzare la classe BatchedJoinBlock<T1, T2> per acquisire i risultati e tutte le eccezioni che si verificano durante l'esecuzione del programma viene letto da un database.

Procedura dettagliata: creazione di un tipo di blocco di flussi di dati personalizzato

Vengono illustrati due modi per creare un tipo di blocco del flusso di dati che implementa il comportamento personalizzato.

Task Parallel Library (TPL)

Introduce la libreria TPL, una libreria che semplifica la programmazione parallela e simultanea delle applicazioni .NET Framework.

Il documento è risultato utile?
(1500 caratteri rimanenti)

Aggiunte alla community

AGGIUNGI
© 2013 Microsoft. Tutti i diritti riservati.