Как лучше всего отладить создание нежелательных потоков в веб-приложении ASP.NET - PullRequest
0 голосов
/ 08 декабря 2010

После IISRESET на моем общедоступном веб-сервере инициализация моего приложения кажется корректной.Таким образом, в событии Application_Start я запускаю новый поток «электронной почты», цель которого состоит в том, чтобы спать до заданного времени, после «пробуждения» создает отчет и отправляет его по электронной почте моим администраторам и возвращается в спящий режим до настроенного времени.По истечении этого времени отчет создается снова и отправляется по электронной почте.В настоящее время я настроен на запуск в 1900 и выдаю новый отчет каждые 12 часов.

С течением времени на этом производственном сайте, однако, что-то вызывает создание «дополнительной» нити.Это, в свою очередь, приводит к отправке по электронной почте дубликата отчета.В то время как проблема достаточно мягкая, я хотел бы очистить это, если это возможно.Вот фрагмент:

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

Изучая журнал событий приложений на веб-сервере, я могу правильно увидеть вышеупомянутое сообщение при IISRESET.За этим следует еще одно «правильное» зарегистрированное событие в workerThread , которое сообщает нам, как долго код будет находиться в режиме ожидания до следующего времени отчета.Вот фрагмент кода 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

Кажется, что вышеприведенный код работает нормально (как я уже говорил, после IISRESET я вижу одно зарегистрированное событие из события Application_Start, за которым следует запись журнала из моегоПоток "email": "EmailThread будет спать в течение nnn минут ... и т. д.". Но каким-то образом (со временем) я получаю другой экземпляр EmailThread, который выдает 2 отчета вместо одного в запланированное "время пробуждения".

В пуле приложений IIS, назначенном этому веб-сайту, у меня есть следующие настройки:

- 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

Я заметил, что событие Application_Start может быть введено снова (в одном случае примерно через 38 минут послев первый раз), что приводит к повторному запуску моего кода и созданию другого [и нежелательного] потока.

Буду признателен за предложения о том, как это исправить, чтобы этот симптом исчез.

Ответы [ 2 ]

1 голос
/ 08 декабря 2010

Я могу вспомнить, что в вашем приложении в IIS есть дополнительное приложение (преобразование виртуальной папки в приложение) в одной из подпапок вашего веб-сайта.

Счетчики производительности ASP.NET также могут помочь вам с количеством созданных приложений и потоков. Используйте perfmon, чтобы следить за ними.

0 голосов
/ 08 декабря 2010

Не понятно, почему, но было бы легко проверить флаг в объекте приложения, проверить его во время запуска и, если установлено, вернуть.

...