StreamWriter Multi Threading C #

Vorrei chiedere aiuto sul mio codice. Sono un principiante e volevo implementare il multi threading sicuro in scrittura su un file di testo.

StreamWriter sw = new StreamWriter(@"C:\DailyLog.txt"); private void Update(){ var collection = Database.GetCollection("products"); StreamReader sr = new StreamReader(@"C:\LUSTK.txt"); string[] line = sr.ReadLine().Split(new char[] { ';' }); while (!sr.EndOfStream) { line = sr.ReadLine().Split(new char[] { ';' }); t = delegate { UpdateEach(Convert.ToInt32(line[5])); }; new Thread(t).Start(); } sr.Close(); } private void UpdateEach(int stock) { sw.WriteLine(ean); } 

Non ho ricevuto errori sul mio codice ma sembra che non tutto sia stato scritto sul mio file di testo. Non ho sw.Close() perché so che alcuni thread non erano ancora finiti. Inoltre, come posso implementare sw.Close sapendo che nessun thread è rimasto incompleto. Ho 5 milioni di record nel mio LUSTK.text che deve essere letto da StreamReader e ognuno ha creato un thread e ogni thread accede allo stesso file di testo.

    Non sarai in grado di scrivere contemporaneamente allo stesso autore da diversi thread. L’object non è stato progettato per supportare l’accesso simultaneo.

    Oltre a ciò, l’idea generale di scrivere sullo stesso file da più thread è difettosa. Hai ancora solo un disco fisico e può girare solo così velocemente. Dire che fare le cose più velocemente non lo farà girare più velocemente.

    Oltre a ciò, non stai chiudendo lo scrittore, come hai detto tu, e come risultato, il buffer non viene scaricato.

    Hai anche un bug nel fatto che il tuo metodo anonimo sta chiudendo la line e tutti i metodi stanno chiudendo la stessa variabile, che sta cambiando. È importante che chiudano ciascuno il proprio identificatore che non cambierà. (Questo può essere ottenuto semplicemente dichiarando la line all’interno del ciclo while .) Ma dato che non dovresti usare più thread per cominciare, non c’è bisogno di concentrarsi su questo.

    È inoltre ansible utilizzare File.ReadLines e File.WriteAllLines per eseguire il file IO; risulta in un codice molto più pulito:

     var values = File.ReadLines(inputFile) .Select(line => line.Split(';')[5]); File.WriteAllLines(outputFile, values); 

    Se si volesse parallelizzare questo processo sarebbe perché si sta facendo del lavoro legato alla CPU su ciascun elemento dopo aver letto la riga e prima di scrivere la riga. Parallelizzare il file effettivo I / O, come detto prima, rischia di essere dannoso, non utile. In questo caso il lavoro con CPU vincasting sta semplicemente dividendo la linea e prendendo un valore, e questo è probabilmente incredibilmente veloce rispetto al file IO. Se è necessario, ad esempio, colpire il database o eseguire alcune elaborazioni costose su ciascuna riga, si prenderà in considerazione la parallelizzazione di quella parte del lavoro, mentre si sincronizza il file I / O con un singolo thread.

    Un StreamWriter semplicemente non è thread-safe; sarà necessario sincronizzare l’accesso a questo tramite lock o simile. Tuttavia, consiglierei di ripensare alla tua strategia in generale:

    • l’avvio di molti thread è una pessima idea – i thread sono in realtà piuttosto costosi, e non dovrebbero essere usati per piccoli lavori (un Task o il ThreadPool potrebbe andare bene, però) – un basso numero di thread che potrebbero staccarsi separatamente da una discussione -Sarà preferibile la coda sicura
    • non avrai alcuna garanzia di ordine in termini di output
    • francamente, mi aspetto che IO sia il tuo più grande problema di prestazioni qui, e questo non è influenzato dal numero di thread (o peggio: può essere influenzato negativamente )