公開されているウェブサーバーで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
Webサーバーのアプリケーションイベントログを調べると、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イベントからの1つのログイベントに続いて、「email」スレッドからのログエントリが表示されます。「EmailThreadはnnn分間スリープします...など。 "。しかし、どういうわけか(時間の経過とともに)EmailThreadの別のインスタンスを取得しているため、スケジュールされた「ウェイクタイム」に1つだけではなく、2つのレポートが生成されます。
このWebサイトに割り当てられている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イベントを再度入力できることに気付きました(1つのケースでは最初の約38分後)。これにより、コードが再度実行され、別の[不要な]スレッドが作成されます。
この症状を解消するためにこれを締める方法についての提案をいただければ幸いです。