MultiThread o cos'altro ??

giovedì 16 giugno 2011 - 16.32

zenx Profilo | Newbie

Ciao a tutti , avrei bisogno di qualche suggerimento per il seguente problema:
Ho scritto un metodo che fa il parsing di file , posizionati in una cartella.
Ipotizzando che io abbia 10 file da parsare, vorrei poter scrivere a video il risultato dell'elaborazione , ogni volta che il metodo finisce di processare un file e non attendere la fine del parsing di tutti i files.
Considerando che le chiamate al server , di norma sono sincrone, io potrei avere i risultati a video dei parsing solo alla fine di tutte i 10 parsing.
Ma questo gia lo faccio . Vorrei farlo nel modo descritto sopra...che risulta più "elegante"

Credo si tratti di dover usare il namespace Threading , ma ho difficolta...
Qualsiasi suggerimento sarà apprezzato
Grazie
Saluti a tutti

alx_81 Profilo | Guru

>Ciao a tutti , avrei bisogno di qualche suggerimento per il seguente problema:
ciao

>Ho scritto un metodo che fa il parsing di file , posizionati
>in una cartella.
>Ipotizzando che io abbia 10 file da parsare, vorrei poter scrivere
>a video il risultato dell'elaborazione , ogni volta che il metodo
>finisce di processare un file e non attendere la fine del parsing
>di tutti i files.
>Considerando che le chiamate al server , di norma sono sincrone,
>io potrei avere i risultati a video dei parsing solo alla fine
>di tutte i 10 parsing.
>Ma questo gia lo faccio . Vorrei farlo nel modo descritto sopra...che
>risulta più "elegante"
Stiamo parlando di web, quindi per gestire le chiamate asincrone dovrai sfruttare la tecnologia AJAX.
Di solito utilizzo jQuery anche per questo tipo di chiamate, ma con Visual Studio e l'ajax toolkit dovresti avere anche i controlli proprietari MS.
Con jQuery le chiamate asincrone le fai col metodo post(): http://api.jquery.com/jQuery.post/

questo metodo va a server, lancia una funzione e gestisce la callback della stessa.
Potresti chiamare una funzione che effettua il parsing di tutti i tuoi file e, ad ogni ciclo, aggiorni su server lo status di ognuno di essi.

La pagina web, tramite un semplice polling fatto con un timer js va a fare refresh di una sola sua parte (sempre con jQuery per leggere da server) per dare feedback grafico all'utente.

>Grazie
di nulla!
--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

Gluck74 Profilo | Guru

Per gestire chiamate asincrone, ci sono diverse possibilità.
Visto che Alex ti ha già proposto la soluzione puramente ajax, io ti propongo una soluzione che utilizza Thread separati ed il partialrendering della pagina con un polling per verificare lo stato.

Purtroppo non è possibile utilizzare la classe System.ComponentModel.BackgroundWorker, poiché in asp.net non ci da il risultato che ci aspettiamo, ovvero la pagina non termina fino a che non termina anche il backgroundWorker (tutto si ferma al PreRenderComplete).

Allora ci facciamo una classe che fa più o meno la stessa cosa, utilizzando un Thread separato:
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Per utilizzare questa classe bastano poche righe di codice, e memorizziamo il tutto in session:

BackgroundWorker worker = new BackgroundWorker(); worker.DoWork += new BackgroundWorker.DoWorkerEvH(worker_DoWork); worker.RunWorker("eventuale parametro di input"); Session["worker"] = worker; Timer1.Enabled = true;

Questo codice può essere eseguito ad esempio al click di un pulsante, rigorosamente dentro un UpdatePanel assieme ad un timer (sidabilitato).
Il timer eseguirà appunto il polling per leggere in session il valore progress del worker ed anche il risultato finale.
Di seguito la procedura da far eseguira al worker ed un esempio di lettura da parte del timer:
void worker_DoWork(ref int progress, ref object result, params object[] args) { string input = string.Empty; if (args.Length > 0) input = args[0].ToString(); //una operazione che richiede tempo //esempio un ciclo di 10 secondi for (int i = 0; i < 100; i++) { Thread.Sleep(100); progress++; } result = string.Format("Input: \"{0}\". - Operazione completata.", input); }

protected void Timer1_Tick(object sender, EventArgs e) { BackgroundWorker worker = (BackgroundWorker)Session["worker"]; if (worker != null) { //visualizzare il progress con una semplice label o con una progressBar //lblProgress = string.Concat("percentuale: ", worker.Progress, "%"); Timer1.Enabled = worker.Progress < 100; } }

____________
Ricordati di utilizzare il tasto "Accetta" se i nostri consigli ti sono serviti a risolvere il problema.
È il modo per ringraziare chi ti ha aiutato.
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5