193 messaggi dal 12 febbraio 2016
Buonasera a tutti,
ho un metodo statico che richiama al suo interno un altro metodo statico tramite un altro Thread. Questo secondo metodo aggiorna il contenuto di una tabella del database e invia una mail.
Il problema che sto avendo è che l'aggiornamento della tabella avviene correttamente, l'invio della mail no.

Ci sono problemi ad inviare una mail (utilizzando il namespace System.Net.Mail) con un Thread separato?
Questo è il codice che utilizzo:

public static void Metodouno(string parametro)
{
            Thread t = new Thread(() => Metododue(parametro));
            t.Start();
            // altro codice del metodo metodouno
            t.Abort();
}

protected static void Metododue(string parametro)
{

  // codice del metodo metododue

}



Grazie a tutti
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao,
non dovrebbero esserci problemi però vedo che invochi il metodo Abort(), come mai?
Che succede se l'invio della mail non si è ancora completato quando invochi Abort()? Hai provato ad inviare la mail nel thread principale? In quel caso arriva?

Comunque, penso che tu possa semplifare un po' il codice. L'uso esplicito dei Thread è stato sostituito dati Task e, infatti, in questo caso specifico non è neanche richiesto il multithreading.

Se vuoi compiere le due operazioni contemporaneamente (aggiornamento tabella e invio email) puoi fare così. I metodi li crei asincroni.
public static async Task AggiornaTabella(string parametro)
{
    //aggiorna la tabella
    //await dbContext.SaveChangesAsync();
}

protected static async Task InviaMail(string parametro)
{
    //Invia la mail
    //await smtpClient.SendAsync();
}


E poi li mandi in esecuzione "parallelamente". In realtà il seguente codice non richiede il multithreading dato che sia l'aggiornamento al db che l'invio della mail sono operazioni di I/O di lunga durata che non hanno bisogno che un thread sia lì ad aspettare che abbiano finito.
var taskTabella = AggiornaTabella("parametro");
var taskMail = InviaMail("altroParametro");
//qui eventualmente fai altre cose
//e poi aspetti che entrambi abbiano finito
await Task.WhenAll(new[] { taskTabella, taskMail });
//Qui entrambi i task sono completati, restituisci un risultato all'utente
//Se vuoi, avvolgi tutto questo pezzo di codice con un try catch per catturare eventuali eccezioni


ciao,
Moreno
Modificato da BrightSoul il 04 marzo 2017 20.54 -

Enjoy learning and just keep making
193 messaggi dal 12 febbraio 2016
Buona domenica Moreno e grazie per la risposta.
I Task non posso usarli in quanto il server su cui è ospitato il sitoweb usa la versione 4.0.

Io vorrei utilizzare il multithreading in modo che la pagina impieghi meno tempo per caricarsi, "destinando" i due metodi in maniera asincrona. Infatti potrei anche farne a meno della loro risposta in quanto devono aggiornare la tabella e inviare la mail.
Uso il metodo Abort() perché sto utilizzando il codice riportato a questo tutorial: in questo tutorial viene utilizzato il metodo start() e poi il metodo Abort().

La mia necessità non è quella di compiere due operazioni contemporaneamente, ma quella di delegare delle operazioni ad un thread separato in maniera tale da far lavorare di meno il thread principale e non appesantire la pagina.

Grazie di tutto
ciao
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao,


potrei anche farne a meno della loro risposta in quanto devono aggiornare la tabella e inviare la mail.

Ok ma così come fai a garantire all'utente che le due operazioni hanno avuto successo?
Cioè, vuoi che la pagina si carichi velocemente ma poi non sai se di fatto la mail è stata inviata o se la tabella è stata aggiornata?

Il fatto che la pagina debba caricarsi velocemente è sacrosanto, però devi anche darti un modo di monitorare il corretto svolgimento delle operazioni che l'utente dispone. Se si verifica un errore, devi essere in grado di avvisarlo a posteriori.

Ora, la soluzione rapida al tuo problema consiste probabilmente nel togliere l'Abort, che interrompe il thread. Però vorrei anche guidarti sulla soluzione corretta a questo problema.
  • Abbandona la creazione di thread espliciti, sono stati sostituiti dai Task. Li puoi usare nel .NET Framework 4.0, anche senza async/await. Usa Task.Factory.StartNew per avviare il task, poi deciderai se attenderne il completamento o no.
  • Oppure, per operazioni di lunga durata da lanciare in background, dovresti affidarti ad un pacchetto tipo HangFire. In questa discussione abbiamo visto un esempio di come sia possibile avviare un'operazione di lunga durata e poi tornare a monitorarla in qualsiasi momento.
    http://forum.aspitalia.com/forum/post/412306/DataSet.ReadXml-Valori-Consentiti.aspx?PageIndex=3#412615
    Nel tuo caso potresti avvisare l'utente solo se si verifica un errore nell'esecuzione del task in background.


ciao,
Moreno
Modificato da BrightSoul il 05 marzo 2017 17.41 -

Enjoy learning and just keep making
193 messaggi dal 12 febbraio 2016
Ti ringrazio tanto Moreno,
quindi modificando il mio Metodouno così andrebbe bene?

public static void Metodouno(string parametro)
{
        var myTask = Task.Factory.StartNew(() => AggiornaQuantita(code));
        // altro codice del metodo metodouno
        myTask.Wait();
}

protected static void Metododue(string parametro)
{

  // codice del metodo metododue

}


Grazie ancora
buona giornata
11.886 messaggi dal 09 febbraio 2002
Contributi
Sì, dovrebbe andare. Funziona?

Enjoy learning and just keep making
193 messaggi dal 12 febbraio 2016
Si funziona benissimo.
Solo che la mail continua a non arrivare ma ho scoperto il motivo:
Per recuperare l'indirizzo email del destinatario utilizzo una mia dll contenente una classe statica.
Il metodo che recupera l'indirizzo email usa due proprietà di tipo stringa impostate come static e readonly.
Ora, quando il metododue lavora con task separato mi viene restituita un'eccezione dicendo che non trova il valore di queste due proprietà; quando invece sempre il metododue lavora con il task principale allora funziona perfettamente.
Come mai? Come posso risolvere questo problema?
grazie come sempre del supporto che dai.
193 messaggi dal 12 febbraio 2016
Ciao Moreno,
sapresti suggerirmi come risolvere questo problema?
Saluti

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.