2010-08-19 34 views
10

Ho un file xml che deve essere letto da molte molte volte. Sto cercando di utilizzare Parallel.ForEach per accelerare questo processo poiché nessuno di quei dati letti è rilevante per l'ordine in cui viene letto. I dati vengono semplicemente utilizzati per popolare gli oggetti. Il mio problema è anche se sto aprendo il file ogni volta nel thread in quanto letto solo si lamenta che è aperto da un altro programma. (Non l'ho aperto in un editor di testo o altro :))Più thread che leggono dallo stesso file

Come posso eseguire più letture dallo stesso file?

MODIFICA: il file è ~ 18KB piuttosto piccolo. Si legge da circa 1800 volte.

Grazie

+4

Il disco rigido ha ancora solo una testina in modo da poter eseguire solo una lettura alla volta. Che miglioramento delle prestazioni ti aspetti da questo? – Daniel

+1

Il file si adatta alla cache del disco? Se è così, quindi più letture sarà veloce, altrimenti se il file è abbastanza piccolo da adattarsi alla memoria, quindi utilizzare un file mappato in memoria invece e leggere da quello. In caso contrario, il disco rigido impiegherà molto tempo a battere piuttosto che eseguire letture sequenziali e perderai le prestazioni piuttosto che ottenerle. – mdma

+1

Una testa su un disco rigido? Sono abbastanza sicuro che anche le unità a singolo piatto abbiano più teste in questi giorni, così come il caching, ecc. Che risolvono rallentamenti specifici della testa. – GrayWizardx

risposta

24

Se si desidera più thread di leggere dallo stesso file, è necessario specificare FileShare.Read:

using (var stream = File.Open("theFile.xml", FileMode.Open, FileAccess.Read, FileShare.Read)) 
{ 
    ... 
} 

Tuttavia, non sarà possibile ottenere alcun aumento di velocità da questa, per diverse ragioni:

  1. Il tuo hard disk può solo leggere una cosa alla volta. Sebbene siano attivi più thread contemporaneamente, questi thread finiranno per attendere l'un l'altro.
  2. Non è possibile analizzare facilmente una parte di un file XML. Di solito devi analizzare l'intero file XML ogni volta. Poiché hai più thread che lo leggono continuamente, sembra che non ti aspetti che il file cambi. Se questo è il caso, allora perché hai bisogno di leggerlo più volte?
+0

+1 Per i commenti "1" e "2". FileAccess.Read e FileShare.Read NON risolveranno il problema, quando più thread tentano di leggere lo stesso file. Quindi, come accennato nel commento "2" se abbiamo solo bisogno di leggerlo, allora possiamo prima leggerlo una volta e poi dare a "fare l'elaborazione" per più thread. – Vytas999

+0

Per quanto riguarda il punto 1, questo non è applicabile a cose come gli array di dischi, che per il software del server sarebbero facili da prevedere. – Matt

1

Quando si apre il file, è necessario specificare FileShare.Read:

using (var stream = new FileStream("theFile.xml", FileMode.Open, FileAccess.Read, FileShare.Read)) 
{ 
    ... 
} 

In questo modo il file può essere aperto più volte per la lettura

+4

mentre ciò è corretto, a meno che il poster non divida il file in blocchi, è dubbio che si verificherà una reale velocità utilizzando più thread. –

+3

@Mitch Wheat: davvero. Ma sto solo rispondendo alla domanda del PO, non giudicare se l'utilizzo di più thread è una buona idea;) –

+1

insegnare a un uomo a pescare e tutto ciò che .... –

3

A seconda delle dimensioni del file e il tipo di letture che stai facendo potrebbe essere più veloce per caricare prima il file in memoria e quindi fornire l'accesso direttamente ai tuoi thread.

Non hai fornito alcun dettaglio sul file, le letture, ecc., Quindi non posso dire con certezza se risponda alle tue esigenze specifiche.

La premessa generale sarebbe quella di caricare il file una volta in un singolo thread e quindi direttamente (tramite la struttura Xml) o indirettamente (tramite XmlNodes, ecc.) Fornire l'accesso al file a ciascuno dei thread. Mi immagino qualcosa di simile a:

  1. Caricare il file di
  2. Per ogni query XPath spedizione i nodi corrispondenti alle vostre discussioni.

Se i thread non modificano direttamente l'XML, questa potrebbe essere un'alternativa valida.

+0

cercherò di caricarlo in memoria, grazie per l'idea. – Pieces

Problemi correlati