Domanda

Ho qualche codice di trasferimento di file ad alta prestazione che ho scritto in C # utilizzando il modello di programmazione asincrona (APM) linguaggio (ad esempio, BeginRead / EndRead). Questo codice legge un file da un disco locale e lo scrive in una presa.

Per ottenere le migliori prestazioni su hardware moderno, è importante mantenere più di una straordinaria operazione di I / O in volo, quando possibile. Così, ho posto diverse operazioni BeginRead sul file, poi, quando si completa, che io chiamo un BeginSend sul socket, e quando che completa faccio un'altra BeginRead sul file. I dettagli sono un po 'più complicato di così, ma per l'alto livello che è l'idea.

Ho il codice di lavoro APM-based, ma è molto difficile da seguire e probabilmente ha bug di concorrenza sottili. Mi piacerebbe utilizzare TPL per questo, invece. I Task.Factory.FromAsync figurato sarebbe solo di farlo, ma c'è un problema.

Tutti i campioni di I / O che ho visto (in modo particolare la classe StreamExtensions nel parallelo estensioni Extra) assumere una LEGGI seguito da una scrittura. Questo non eseguirà la necessità mio modo.

Non è possibile utilizzare qualcosa di semplice come Parallel.ForEach o l'estensione Task.Factory.Iterate Extra perché i compiti asincrone di I / O non spendere molto tempo su un thread di lavoro, in modo parallelo appena si avvia un altro compito, con conseguente potenzialmente decine o centinaia di in attesa di operazioni di I / O; modo troppo! È possibile risolvere che Waiting sui vostri compiti, ma che provoca la creazione di un manico evento (un oggetto di kernel), e un'attesa di blocco su un manico compito attesa, che lega in su un thread di lavoro. La mia implementazione APM-based evita entrambe le cose.

Ho suonato in giro con diversi modi per mantenere più operazioni di lettura / scrittura in volo, e sono riuscito a farlo utilizzando continuazioni che chiamare un metodo che crea un altro compito, ma ci si sente a disagio, e sicuramente doesn' t voglia TPL idiomatica.

Qualcun altro ha cimentati con un problema come questo con il TPL? Qualche suggerimento?

È stato utile?

Soluzione

Se siete preoccupati per troppi thread, si può semplicemente insieme ParallelOptions.MaxDegreeOfParallelism ad un numero accettabile nella vostra chiamata a Parallel.ForEach.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top