Frage

Ich versuche einen kleinen E -Mail -Mitarbeiter zu erstellen, der meine E -Mails sendet. Der E -Mail -Mitarbeiter betreibt in seinem eigenen Thread. Der Global.asax startet den Thread und läuft dann für eine Runde, bevor er diese Ausnahme auswirft. Ich habe versucht herauszufinden, wohin es es wirft, aber es scheint jedes Mal anders zu sein. Die Datensätze werden in die Textdatei gedruckt, damit die Entsendungsfunktionen funktioniert?

Dies ist die Ausnahme:

Starten Sie eine neue Runde im E-Mail-Arbeiter für Loop
Schlafen Sie im E-Mail-Arbeiter für Loop schlafen
Eine Ausnahme der ersten Chance von Typ 'System.Threading.Threadabortexception' trat in mscorlib.dll auf
Eine Ausnahme von Typ 'System.Threading.Threadabortexception' trat in mscorlib.dll auf, wurde jedoch nicht im Benutzercode behandelt

Dies ist der Code für den E -Mail -Mitarbeiter

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;
            }
        }
    }
}

Dies ist die Global.asax -Datei, die alles startet:

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;
}
War es hilfreich?

Lösung

Der Thread, den Sie erstellen, wird von ASP.NET abgebrochen. Das Erstellen von langlebigen Threads ist in ASP.NET ein wichtiges No-No.

A Wir haben eine Arbeitsumgehung, auf die wir nicht stolz sind ... Erstellen Sie einen Timer, der anhängige E -Mails verarbeitet.

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)

Um beim Timer_Tick -Event besonders sorgfältig zu sein, handeln Sie bei den meisten N -E -Mails, damit der Timer Tick endet und eine neue steigt ...

Dies arbeitet an unserer Produktionsumgebung ...

Andere Tipps

Sie müssen den E -Mail -Arbeitnehmer von ASP.NET in Windows Service verschieben. Sie können zwischen Ihrer Webseite und dem Dienst über WCF kommunizieren. ASP.NET ist nicht für langjährige Aufgaben gedacht.

Das ThreadAbortException tritt auf, wenn Ihre Anwendung abgeschaltet wird und Sie anrufen EmailWorkerThread.Abort(). Dies ist ein Verhalten erwartet und erfolgt an zufälligen Stellen Application_End Anrufe Abort() auf dem Thread.

Wie per Msdn, das ThreadAbortException ist eine besondere Ausnahme, die auch nach dem Umgang mit Ihrem Code immer überlegt wird. Es soll Sie wissen lassen, dass der Thread geschlossen wird, um Ihnen die Möglichkeit zu geben, aufzuräumen.

Ihre Anwendung wird wahrscheinlich heruntergefahren, da IIS den Arbeitsprozess nach einer festgelegten Leerlaufzeit oder einer anderen auferlegten Einschränkung senkt. Auch dies ist zu erwarten, dass ASP.NET -Anwendungen in der Regel "begrenzte Lebensdauer" haben, so dass lange Laufdhreads wie diese keine wirklich gute Idee sind.

Ich bin mir nicht sicher, was Ihre genaue Frage war, aber hoffentlich habe ich es beantwortet.

Der Kinderfaden kann nur so lange leben, wie der übergeordnete Thread lebt. Obwohl Sie einen Thread in einer anscheinend anscheinend erscheinenden Anwendungsebene definieren, kann ich mir nicht vorstellen, dass dieser Thread tatsächlich außerhalb des Httprequest -Threads überlebt. Für mich bedeutet dies, dass der Moment, in dem Ihr Anforderungs -Thread endet, Ihr Kinder -E -Mail -Arbeiter -Thread beendet. Da der Thread schläft, versucht die nächste Zeile auszuführen, kann es jedoch nicht, weil der Httprequest -Thread bereits seinen Kurs ausgeführt hat.

ThreadAbortException Wie der Name schon sagt, wird ein Thread geworfen, wenn ein Thread funktioniert und abgebrochen wird. Dies geschieht an diesem Ort:

 EmailWorkerThread.Abort();

Es kann nicht gefangen werden und passiert, wenn Ihre Bewerbung endet.

Eine bessere Implementierung wäre, die unendliche Schleife durch zu ersetzen stornierbar Schleife.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top