0

在我面向公衆的web服務器上的IISRESET之後,我的應用程序的初始化似乎正確。也就是說,在Application_Start事件中,我將啓動一個新的「電子郵件」線程,其目的是在配置的時間內休眠,在「喚醒」時生成報告並通過電子郵件將其發送給我的管理用戶並返回到睡眠狀態,直到配置完成持續時間過後,報告再次創建並通過電子郵件發送出去。我目前配置爲從1900年開始,每12小時產生一份新報告。如何在ASP.NET Web應用程序中最好地調試不需要的線程

隨着時間的遊行與此生產現場,然而,有些東西是造成「額外」的線程創建。這反過來又會導致重複報告被通過電子郵件發送。雖然問題是足夠的,但如果可能的話,我想清理一下。這裏有一個片段:

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事件,然後從我的「電子郵件日誌條目的一個記錄的事件「跟帖:‘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分鐘後),這會導致我的代碼再次運行並創建另一個[和不需要的]線程。

我將不勝感激就如何收緊這件事使這個症狀消失建議。

+0

使用一生中有99%生命的線程真的是最好的方法嗎?你是否可以不使用計時器並在經歷的事件中完成你的工作?無論如何,您總是可以使用您在啓動線程時設置的靜態屬性,並在應用程序結束時將其殺死時清除它。如果該屬性已設置,則不要啓動更多線程(例如,布爾值)。 – 2010-12-07 22:57:06

+0

另外,我假設您只使用1臺服務器(沒有計劃添加額外的服務器)來託管您的應用程序。每個人都會開始自己的主題並嘗試發送電子郵件。 – 2010-12-07 22:58:50

回答

1

我能想到的是,在IIS應用程序,你有你的網站的子文件夾中的一個額外的應用程序(虛擬文件夾轉換爲應用程序)。

ASP.NET性能計數器還可以幫助您創建的應用程序和線程數。使用perfmon來監視它們。

0

不明白爲什麼,但它會很容易在應用對象來檢查一個標誌,啓動時檢查,如果設置的回報。

相關問題