Question

Je suis en train de construire un petit travailleur de courrier électronique qui envoie mes e-mails. Le travailleur de courrier électronique fonctionne dans son propre fil. Le global.asax commence le fil et il court pour un tour avant de lancer cette exception. J'ai essayé de savoir où il jette, mais il semble être différent à chaque fois. Les enregistrements sont imprimés dans le fichier texte afin que les travaux, peut-être les fonctions Dispose?

Ceci est l'exception levée:

  

Démarrage d'un nouveau cycle dans l'e-mail   travailleur en boucle
  Aller dormir dans la   travailleur email boucle
  Une première chance   exception de type   'System.Threading.ThreadAbortException'   est produite dans mscorlib.dll
  Une exception   de type   'System.Threading.ThreadAbortException'   est produite dans mscorlib.dll mais n'a pas été   manipulés dans le code utilisateur

Ceci est le code pour le 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;
            }
        }
    }
}

Ceci est le fichier global.asax qui commence tout:

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;
}
Était-ce utile?

La solution

Le fil que vous créez est avortent par asp.net. Créer de longs fils sont en cours d'exécution un grand non-non en asp.net.

nous avons une solution de travail, que nous ne sommes pas fiers de ... Créer une minuterie qui processus emails en attente.

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)

Pour être carefull supplémentaire, au cas Timer_Tick, poignée à la plupart des e-mails de N, de sorte que les extrémités de timer tick, et une nouvelle monte ...

travaille sur notre environnement de production ...

Autres conseils

Vous devez déplacer le EmailWorker sur ASP.NET et en service Windows. Vous pouvez communiquer entre votre page Web et le service via WCF. ASP.NET n'est pas pour les tâches à long en cours d'exécution.

Le ThreadAbortException se produit lorsque votre application se ferme vers le bas et que vous appelez EmailWorkerThread.Abort(). Ce comportement est normal et il se produit dans des endroits aléatoires car le code peut être dans les différents « points » lorsque les appels Application_End Abort() sur le fil.

par MSDN , le ThreadAbortException est un exception spéciale qui est toujours relancée même après avoir été manipulé par votre code. Il est destiné à vous faire savoir que le fil est en cours d'arrêt pour vous donner l'occasion de nettoyer.

application Vous est en cours d'arrêt probablement vers le bas parce que IIS est en cours d'arrêt du processus de travail après un certain laps de temps d'inactivité, ou une autre limitation imposée. Encore une fois, cela est à prévoir, les applications ASP.NET ont tendance à avoir « durée de vie limitée », en cours d'exécution tant des fils comme celui-ci ne sont pas vraiment une bonne idée.

Je ne sais pas quelle était votre question exacte, mais je l'espère, je répondu.

Le fil de l'enfant ne peut vivre aussi longtemps que le fil parent est vivant. Même si vous avez un fil défini dans ce qui semble être le niveau de l'application, je ne peux pas imaginer ce fil survive à l'extérieur du fil HttpRequest. Pour moi, cela signifie que le moment votre demande de fil se termine, votre enfant EmailWorkerThread se termine. Etant donné que le fil est en train de dormir, les tentatives de nouvelle ligne pour exécuter, mais il ne peut pas parce que le fil HttpRequest a déjà couru son cours.

ThreadAbortException comme son nom l'indique, est jeté lorsqu'un thread fonctionne et est abandonnée. Cela se produit à cet endroit:

 EmailWorkerThread.Abort();

Il ne peut pas être pris et il se produit lorsque vous application se termine.

serait une meilleure mise en œuvre pour remplacer la boucle infinie avec résiliable boucle .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top