Domanda

sto cercando di costruire un piccolo operaio e-mail che manda le mie email. Il lavoratore e-mail opera nel proprio thread. Il global.asax inizia il filo e poi si corre per un turno prima di gettare questa eccezione. Ho cercato di scoprire dove si butta, ma sembra essere diverso ogni volta. I record vengono stampate su file di testo in modo che le opere, forse le funzioni Smaltire?

Questa è l'eccezione generata:

Avvio di un nuovo round nella e-mail lavoratore per-loop
Andare a dormire nel operaio e-mail per-loop
Una prima occasione eccezione di tipo 'System.Threading.ThreadAbortException' verificata in mscorlib.dll
Un'eccezione di tipo 'System.Threading.ThreadAbortException' in mscorlib.dll ma non era trattati in codice utente

Questo è il codice per l'EmailWorker

public static class EmailWorker
{
    public static void Work()
    {
        TimeSpan sleepTime = new TimeSpan(0, 1, 0);

        for (; ; )
        {
            Debug.WriteLine("Starting a new round in the email worker for-loop");
            try
            {
                // Get the records
                CS_Code.UtopiaDataContext db = new CS_Code.UtopiaDataContext(); 
                List<CS_Code.Global_Email> emailsToSend = (from xx in db.Global_Emails select xx).ToList();


                // Write the records to a file (for now)
                TextWriter writer = new StreamWriter(@"test.txt", true); // For debugging
                foreach (var email in emailsToSend)
                    writer.WriteLine("To: " + email.Email_Address + ", Subject: " + email.Subject + ", uid:" + email.UserName.ToString());
                writer.Close();
                writer.Dispose();

                // Delete the used records from the database
                foreach (var email in emailsToSend)
                    db.Global_Emails.DeleteOnSubmit(email);
                db.SubmitChanges();
                db.Dispose();


                Debug.WriteLine("Going to sleep in the email worker for-loop");
                Thread.Sleep(sleepTime); // Sleep for 1 minute.
                Debug.WriteLine("Just woke up in the email worker for-loop");
            }
            catch (Exception e)
            {               
                Debug.WriteLine(e.Message);
                break;
            }
        }
    }
}

Questo è il file Global.asax che inizia tutto:

private static Thread EmailWorkerThread { get; set; }

void Application_Start(object sender, EventArgs e)
{
    // Email worker thread
    if ((EmailWorkerThread == null) || (!EmailWorkerThread.IsAlive))
    {
        ThreadStart ts = new ThreadStart(EmailWorker.Work);
        EmailWorkerThread = new Thread(ts);
        EmailWorkerThread.Start();
    }
}

void Application_End(object sender, EventArgs e)
{
    // Email worker thread
    if ((EmailWorkerThread != null) || (EmailWorkerThread.IsAlive))
        EmailWorkerThread.Abort();
    EmailWorkerThread = null;
}
È stato utile?

Soluzione

Il filo che si sta creando viene interrotta da asp.net. Creazione di thread in esecuzione lungo sono un grande no-no in asp.net.

Un abbiamo una soluzione di lavoro, che non siamo orgogliosi di ... Creare un timer che elaborano le email in sospeso.

static Timer processTimer; // declare static at service level

// At the static constructor:
processTimer = new Timer(new TimerCallback(TimerTick), 60000, 10000, defaultInterval); //wait a minute before begin (dueTime = 60000)

Per essere attento in più, durante l'evento Timer_Tick, maniglia a maggior parte dei email N, quindi le estremità timer tick, e uno nuovo si alza ...

Questo è il lavoro sul nostro ambiente di produzione ...

Altri suggerimenti

È necessario spostare l'EmailWorker di ASP.NET e nel servizio di Windows. È possibile la comunicazione tra la tua pagina web e il servizio tramite WCF. ASP.NET non è pensato per le attività a lungo in esecuzione.

Il ThreadAbortException si verifica quando le chiude applicazione verso il basso e si chiamano EmailWorkerThread.Abort(). Questo è il comportamento previsto e si verifica in luoghi casuali, perché il codice può essere in diverse "punti" in cui le chiamate Application_End Abort() sul filo.

Come per MSDN , il ThreadAbortException è un particolare eccezione che è sempre rilanciati anche dopo essere gestita dal codice. E 'destinato a farvi sapere che il filo si sta spegnendo per darvi l'opportunità di ripulire.

applicazione

Si è probabile spegnendo perché IIS è in fase di arresto del processo di lavoro dopo un certo lasso di tempo di inattività, o qualche altra limitazione imposta. Ancora una volta, questo è da aspettarselo, le applicazioni ASP.NET tendono ad avere "durata limitata", in esecuzione così tanto tempo le discussioni di questo tipo non sono davvero una buona idea.

Non sono sicuro di ciò che la vostra domanda esatta era, ma si spera che io ho risposto.

Il thread figlio può solo vivere fino a quando il filo genitore è vivo. Anche se hai un filo definita in quello che sembra essere il livello di applicazione, non riesco a immaginare questa discussione in realtà sopravvive al di fuori del filo HttpRequest. Per me questo significa che il momento i vostri termina thread di richiesta, il bambino EmailWorkerThread termina. Poiché il filo dorme, i tentativi riga successiva da eseguire ma non possono perché il filo HttpRequest ha già il suo corso.

ThreadAbortException come dice il nome, viene generata quando un thread è in funzione e viene interrotta. Questo accade in questo luogo:

 EmailWorkerThread.Abort();

Non può essere catturato e succede quando si finisce di applicazione.

Una migliore attuazione sarebbe di sostituire il loop infinito annullabile ciclo .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top