442 messaggi dal 09 marzo 2006
ciao.
Dato che un esempio parla piu di 100 parole scritte male(perchè sono poco capace di spiegare) lo posto quello che vorrei fare:
namespace open
{

    class processaXml
    {
        public processaXml(){}
        void LeggieProcessa(string file)
        {
            Task processo1;
            Task processo2;

            var lines = new ConcurrentQueue<StringBuilder>();
            var strbuilder = new StringBuilder();

            processo1 = Task.Run(() =>
            {
                using (var reader = new StreamReader(file))
                {
                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        strbuilder.Append(line);
                    }
                }
            });

            processo2 = Task.Run(() =>
            {
              //qui faccio il mio parsing e la deserializzazione
           });

          Task.WaitAll(new Task[] { processo1, processo2 });
        }
    }
}

come vedete ho due task il primo processo1 legge il file e il secondo fa un parsing che puo essere piu o meno complesso e deserializza gli elementi xml che arrivano dal primo task.
1)Non so se è ilmetodo migliore , ma vorrei che quando il parsing diciamo di 100 elementi è finito il processo2 richiede nuove righe e il processo1 gliele manda
2)Moreno mi aveva mandato questo link :

qui c'è un esempio di come puoi notificare il progresso da Task asincroni.

http://blog.stephencleary.com/2012/02/reporting-progress-from-async-tasks.html

questo per usare un evento per la notifica del progresso o una notifica che potrebbe andare bene anche a me
3)io alla fine ho messo il waitall di tutti e due i task in modo che uno faccia sopravvivere l'altro(l'evento di lettura file è quello che comanda alla fine perchè finche ci sono righe il processo2 deve rimanere in vita) ma penso che sia sbagliato e non so come fare si che "un task sopravviva" senza un ciclo infinito che mi occupa un core almeno cosi mi sembra di aver visto nel debug di vs2015 e il task penso proprio che muoia quando ha finito il suo lavoro.
4)Le funzioni asincrone lvorano in modo asincrono sullo stesso thread mi sembra di aver letto qui sul forum e forse sarebbe meglio rivolgersi a queste, Alla fine posso usare le notifiche per richiamare la funzione asincrona al posto del processo2 che esegue il suo lavoro e "muore" oppure richiamare il task dato che ho letto che la creazione di un task è molto meno dispendiosa della creazione di thread.
4)una nota particolare va al continuewith dei task che forse potrebbe aiutare anche senza l'uso di notifiche od eventi quando il processo1 raggiounge per es 1000 righe si fa il continue del task sul processo2 , chiedo non sono per nulla esperto di programmazione asincrona ma ho comperato un buon libro sul c#5.

grazie.
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao Giuseppe,
l'idea di due Task che cooperano non è male, ricalca il modello producer/consumer in cui uno riveste il ruolo di generatore di informazioni e l'altro di consumatore. Si potrebbe implementare facilmente con una BlockingCollection e con la ConcurrentQueue che ho visto nel tuo codice.

Ma.
In questo caso penso che non sia necessario. In fondo, la lettura sequenziale di righe da un file di testo non è poi così onerosa da meritare un Task a parte e perciò l'aggiunta di questa complessità. Potresti trarre più beneficio dal processare parallelamente (cioè in multithreading) le righe che vengono lette.

Vedi questo esempio, che sfrutta la Task Parallel Library.
http://stackoverflow.com/questions/17188357/read-large-txt-file-multithreaded

Potresti incapsulare quel codice in una classe che possiede un metodo per avviare l'elaborazione e un evento che userai per notificare il progresso.
In questo caso notificare il progresso è facile: il peso del file è noto e così anche la lunghezza delle righe lette, quindi puoi andare ad incrementare un intero e sollevare l'evento passando la percentuale calcolata in base al peso del file (che avrai ottenuto in questo modo prima di iniziare l'elaborazione).

Per incrementare e leggere l'intero, usa la classe Interlocked che ti permette di farlo in maniera thread safe.

ciao,
Moreno
Modificato da BrightSoul il 20 luglio 2016 19.53 -

Enjoy learning and just keep making
442 messaggi dal 09 marzo 2006
Ciao moreno alla fine ti ho dato retta le prestazioni tra la versione parallela e quella non parallela erano uguali ed ho unito il generatore di blocchi e la lettura del file nello stesso task.a questo punto i blocchi vanno dessrializzati e ho creato una factory con il tipo e il nome del blocco xml da deserializzare.a questo punto dato il nome la factory mi ritorna un deserializzatore ad hoc per il blocco non resta che usarlo e deserializzare l entita, tutte le entita infatti derivano dalla classe base entity.
Sono di fronte ad un problema:usare un task asincrono per ogni blocco xml lasciarlo processare ed inserire lentity in una currencyqueque o usare un parallel for?tempo fa. Mi avevi detto che le funzioni asincrone. Lavorano sullo stesso thread e corretto?come faccio a divifere il carico di lavoro su piu processori?
Grazie. La deserializOne è il vero consumer.e senza caricare tutto il file in memoria mi deserializza file molto grandi senza problemi.
Ciao.
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao Giuseppe, vai col Parellel.ForEach, così riuscirai a sfruttare più core della tua CPU. Puoi anche controllare il grado di parallelismo attraverso le opzioni.
https://msdn.microsoft.com/it-it/library/system.threading.tasks.paralleloptions.maxdegreeofparallelism(v=vs.110).aspx



Mi avevi detto che le funzioni asincrone. Lavorano sullo stesso thread e corretto?

Sì, è come quando vuoi fare la pasta per pranzo: prendi una pentola, la riempi d'acqua e la metti sul fuoco. A quel punto non stai ad aspettare fermo lì davanti che bolla, ma la lasci andare da sola (cioè fai bollire l'acqua in maniera asincrona) e nel frattempo ti dedichi ad altre attività, tipo prendere un coltello, tagliare il pomodoro fresco, e così via. L'unico cuoco/thread in questo caso sei tu, non ce ne sono altri.

Per una spiegazione più tecnica leggi questo:
http://blog.stephencleary.com/2013/11/there-is-no-thread.html

Giusto quando crei un task con la task factory hai modo di suggerire la creazione di un nuovo thread con l'opzione LongRunning.
https://msdn.microsoft.com/en-us/library/system.threading.tasks.taskcreationoptions(v=vs.110).aspx

Per il tuo scopo però usa Parallel.ForEach.

Enjoy learning and just keep making

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.