Comment mieux déboguer la création de threads indésirables dans l'application Web ASP.NET
-
09-10-2019 - |
Question
Après une IISRESET sur mon serveur web public face, l'initialisation de mon application semble correcte. C'est, en cas Application_Start je lance un nouveau thread « e-mail » dont le but est de dormir jusqu'à ce que le temps configuré, à « réveiller » produire un rapport et l'envoyer à mon utilisateur administratif (s) et rendormir jusqu'à ce que la configuration durée écoulée à laquelle, le rapport est créé à nouveau et adressé par courriel. Je suis actuellement configuré pour commencer à 1900 et un nouveau rapport toutes les 12 heures.
Comme le temps passe sur ce site de production, cependant, quelque chose est à l'origine d'un fil « supplémentaire » à créer. Ceci, à son tour, se traduit par un rapport en double étant envoyées par courrier électronique. Alors que le problème est assez bénin, je voudrais nettoyer cette place si possible. Voici un extrait:
Public Class [Global]
Inherits System.Web.HttpApplication
Public emth As New EmailThread
Private vcomputer As String
Private eventsource As String
Private message1 As String
Public MyInstanceStart As New ThreadStart(AddressOf emth.workerThread)
Public InstanceCaller As New Thread(MyInstanceStart)
Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
vcomputer = System.Environment.MachineName
InstanceCaller.Name = "EMAILBOT"
InstanceCaller.Start()
UIF.WriteToLog("Application_Start: EMAILBOT instance Started")
End Sub
Examiner l'application du journal des événements sur le serveur web, je peux voir le message ci-dessus correctement sur un IISRESET. Il est suivi par un autre événement enregistré « approprié » dans le WorkerThread qui nous indique combien de temps le code dormira avant la prochaine fois du rapport. Voici un extrait de la WorkerThread:
Public Class EmailThread
Public Sub workerThread()
Dim TimeToStart As Date
Dim TimeToStart_Next As Date
Try
Dim Start As Integer = CInt(ConfigurationManager.AppSettings("EmailStartTime"))
Dim iSleep As Integer = CInt(ConfigurationManager.AppSettings("RobotIntervalHours"))
If Start < 1 Or Start > 23 Then Start = 12
If iSleep < 1 Or iSleep > 24 Then iSleep = 12
TimeToStart = New Date(Now.Year, Now.Month, Now.Day, Start, 0, 0)
Do Until TimeToStart > Now
'We missed the start time by some amount...
' compute new time to start by adding RobotIntervalHours
TimeToStart = DateAdd(DateInterval.Hour, iSleep, TimeToStart)
Loop
TimeToStart_Next = DateAdd(DateInterval.Hour, iSleep, TimeToStart)
' 'Set NEXT TimeToStart for reporting
' Compute how long to wait now
Dim SleepMinutes As Long
While 1 = 1
SleepMinutes = System.Math.Abs(DateDiff(DateInterval.Minute, Now, TimeToStart))
strScheduledStart = FormatDateTime(TimeToStart, DateFormat.GeneralDate)
UIF.WriteToLog("EmailThread will sleep for " & CStr(SleepMinutes) & " minutes; " & _
"waking at next starttime: " & strScheduledStart)
Thread.CurrentThread.Sleep(TimeSpan.FromMinutes(SleepMinutes))
'---------------------------------------------------------------------------------------
' Upon waking, resume here:
'---------------------------------------------------------------------------------------
TimeToStart = TimeToStart_Next
TimeToStart_Next = DateAdd(DateInterval.Hour, iSleep, TimeToStart)
BC.NextRobotStartTime = FormatDateTime(TimeToStart, DateFormat.GeneralDate)
StartRobotProcess(strScheduledStart) 'Robot reports generated
SleepMinutes = 0
End While
Catch ex As Exception
UIF.LogException(ex, "CRITICAL: Exception in 'EmailThread.workerThread' has been logged:", 100)
End Try
End Sub
Le code ci-dessus semble fonctionner très bien (comme je l'ai dit, après un IISRESET, je vois celui enregistré l'événement de l'événement Application_Start suivi par l'entrée du journal de mon fils « e-mail »: « EmailThread dormira pendant nnn minutes .. .etc. ». Mais en quelque sorte (au fil du temps), je reçois une autre instance du EmailThread produisant ainsi 2 rapports au lieu d'un seul à l'heure prévue « heure de réveil ».
J'ai dans le pool d'applications IIS affecté à ce site, les paramètres suivants:
- Recycle worker processes (in minutes) is UNCHECKED
- Recycle worker process (number of requests) is UNCHECKED
- Recycle worker process (at various times) is UNCHECKED / nothing specified
- [Idle timeout] Shutdown worker process after being idle for (time in minutes) is UNCHECKED
J'ai remarqué que l'événement Application_Start peut être saisi à nouveau (dans un cas, environ 38 minutes après la première fois) qui provoque mon code à exécuter à nouveau et créer un autre thread [et non désiré].
Je vous serais reconnaissant des suggestions sur la façon de le serrer pour faire de ce symptôme aller.
La solution
Qu'est-ce que je peux penser est que dans votre application dans IIS, vous avez une application supplémentaire (conversion dossier virtuel à la demande) dans l'un des sous-dossiers de votre site Web.
compteurs de performance ASP.NET peut également vous aider avec le nombre d'applications et de threads créés. Utilisez perfmon pour les surveiller.
Autres conseils
ne figure pas pourquoi, mais il serait facile de vérifier un drapeau dans l'objet de l'application, vérifier au démarrage et, si elle est définie, le retour.