2011-01-24 10 views
5

Ho un'applicazione Web e nel codice dietro la pagina, ho un evento clic sul pulsante.Problema di filettatura C# in un'applicazione Web

protected void btnUpload_Click(object sender, EventArgs e) 
     { 
      TimerEvent TE = new TimerEvent(); 
      TE.TimerEvents(); 
      Server.Transfer("~/Jobs.aspx"); 
     } 

Sto avendo una chiamata di metodo TimerEvents() e può richiedere 10-15 secondi per ottenere il controllo al trasferimento del server. quindi voglio che la linea di trasferimento del server sia eseguita simultaneamente nello stesso momento della chiamata al metodo.

ho provato filettatura come qui:

TimerEvent TE = new TimerEvent(); 
    Thread t = new Thread(TE.TimerEvents); 
    t.IsBackground = true; 
    t.Start();   
    Server.Transfer("~/Jobs.aspx"); 

Ma il trasferimento non è fatta, finché il metodo è terminata. Come posso ottenere questo?

+0

Se il metodo è in corso tempo, quindi l'ottimizzazione dovrebbe essere nel metodo. Creando il thread non si renderà il metodo più veloce. È possibile incollare il codice del metodo? – Jagannath

+0

Si suppone che il metodo esegua il polling di una cartella per ogni nuovo file (i nuovi file verranno posizionati in quella cartella dopo l'elaborazione del file di input che sto caricando in quella cartella), quindi l'elaborazione potrebbe richiedere 10-15 secondi che non possono essere ottimizzati (È un file MATLAB e ha bisogno di tempo di porcessing). E non posso far aspettare l'utente per 10-15 secondi. da qui il problema – superstar

risposta

4

Questo design non è l'ideale. Anche se hai capito bene, c'è una possibilità che ti imbatti in problemi lungo la strada a causa della miscelazione del codice multi-threading e della chiamata Server.Transfer().

Ci sono anche problemi riguardanti il ​​multi-threading nelle applicazioni ASP.NET.

Suggerisco di riprogettare l'app in modo da disporre di una sorta di coda che accoda le attività di lunga durata. È quindi possibile disporre di un servizio che elabora le attività in coda una alla volta.

Dall'applicazione web, sarete ora in grado di:

  1. coda il TimerEvents corsa lungo lavoro al servizio esterno.

  2. chiamata Server.Transfer()

  3. Nella nuova pagina ("~/Jobs.aspx"), chiamare il servizio esterno per raccogliere i risultati quando ne avete bisogno.

+0

Vedo il tuo punto. puoi elaborare la coda e il servizio esterno con qualsiasi riferimento per ottenere lo stesso risultato. Grazie – superstar

+0

In realtà ho iniziato a piacermi l'idea che mi hai proposto. Qualsiasi elaborazione su questo sarà molto utile per me. Grazie. – superstar

+0

L'idea è che il servizio esterno eseguirà il polling di una posizione di archiviazione in cui è possibile inserire le richieste. La maggior parte degli sviluppatori utilizza semplicemente una tabella di database con le colonne request_id, request_date, status e request. Tuttavia la stessa cosa può essere ottenuta salvando i file XML su disco o usando MSMQ. Il servizio esegue il polling del percorso di archiviazione, elabora la richiesta e pubblica i risultati, quindi passa alla richiesta successiva. Il chiamante in un secondo momento, può controllare l'area * dei risultati * (o semplicemente la colonna di stato nella tabella DB) per il risultato della richiesta. – tenor

0

Se il processo viene ripetuto in modo simile, spesso, quello che si chiama un "evento applicazione" perché non settup un processo su un thread Sperate dal file Global.asax (applicazione). È possibile utilizzare la classe FileWatcher per monitorare la directory ed elaborare i file in modo sequenziale o avviando un altro processo nel proprio thread per ogni file al loro arrivo, è possibile mantenere uno stato e qualsiasi risultato ed esporlo al client eventualmente utilizzando un AJAX temporizzato richiama.

Ricordarsi di gestire correttamente tutte le eccezioni nei metodi richiamati dal file Global.asax poiché possono portare l'intera AppDomain inattivo.

Global.asax

0

cosa più facile da fare: vorrei solo restituire immediatamente e dire "Tu sei file è stato caricato", ma poi fare un rinfrescante automatico sulla tua pagina 'jobs.aspx' e mostrare lo stato di ogni lavoro come "trattamento" fino a quando è "Fatto"

assumendo jobs.aspx è un elenco dei lavori di elaborazione ... e che 'aggiornamento automatico' non è troppo janky :)