Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何最好地调试ASP.NET web应用程序中不需要的线程的创建_Asp.net_Multithreading_Event Log_Application Start_Address Operator - Fatal编程技术网

如何最好地调试ASP.NET web应用程序中不需要的线程的创建

如何最好地调试ASP.NET web应用程序中不需要的线程的创建,asp.net,multithreading,event-log,application-start,address-operator,Asp.net,Multithreading,Event Log,Application Start,Address Operator,在我的面向公众的Web服务器上设置IIS后,我的应用程序的初始化似乎是正确的。也就是说,在应用程序启动事件中,我启动了一个新的“电子邮件”线程,其目的是在配置的时间之前休眠,在“唤醒”时生成一个报告并通过电子邮件发送给我的管理用户,然后返回休眠状态,直到配置的持续时间过去,此时,报告将再次创建并通过电子邮件发送出去。我目前的配置是从1900开始,每12小时生成一份新报告 然而,随着时间的推移,这个生产站点正在创建一个“额外”线程。这反过来会导致通过电子邮件发送重复的报告。虽然这个问题是良性的,但

在我的面向公众的Web服务器上设置IIS后,我的应用程序的初始化似乎是正确的。也就是说,在应用程序启动事件中,我启动了一个新的“电子邮件”线程,其目的是在配置的时间之前休眠,在“唤醒”时生成一个报告并通过电子邮件发送给我的管理用户,然后返回休眠状态,直到配置的持续时间过去,此时,报告将再次创建并通过电子邮件发送出去。我目前的配置是从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
我注意到可以再次输入Application_Start事件(在一种情况下,大约在第一次输入38分钟后),这会导致我的代码再次运行,并创建另一个(不需要的)线程


我会很感激关于如何加强这一点的建议,以使这一症状消失

不知道为什么,但检查应用程序对象中的标志、在启动时检查标志以及(如果设置)返回标志将很容易。

我能想到的是,在IIS中的应用程序中,您的网站的一个子文件夹中有一个额外的应用程序(将虚拟文件夹转换为应用程序)


ASP.NET性能计数器还可以帮助您确定创建的应用程序和线程的数量。使用perfmon来监视它们。

使用一个花费99%生命周期睡眠的线程真的是最好的方法吗?您是否可以不使用计时器并在经过的事件中执行您的工作?无论如何,您可以始终使用一个静态属性,该属性在启动线程时设置,在应用程序结束时清除。如果设置了该属性(例如布尔值),就不要启动更多线程。另外,我假设您只使用一台服务器(不打算添加其他服务器)来承载应用程序。每个人都会启动自己的线程并尝试发送电子邮件。我相信你可能对这种情况的实际“原因”是正确的(我认为我已经通过添加共享(即静态)解决了眼前的问题)创建线程时设置布尔值,然后进行检查以防止第二次启动线程。事实上,我有类似于您所说的内容。我的默认网站“主目录”选项卡将本地路径指向:c:\zVersion7\site。我有一个名为Zipee的从属虚拟目录,指向同一本地路径。“原因”对于这一点,我希望www.zipeee.com和www.zipeee.com/zipeee指向相同的代码;与此srvrI上的主机头有关。我怀疑这一设置中存在某种原因;我将研究性能计数器,但也许您可以建议如何消除对额外虚拟目录的需求?我认为您的两个应用程序都在他使用相同的应用程序池。为它们创建单独的应用程序池,您的问题将被排序。我用第一个答案中的想法重新编写了代码,问题仍然存在。我尝试更改分配的应用程序池,但仍然存在问题。然后,我在12月7日更仔细地阅读了Aliostad的初始答复,并检查了此网站。果然,此默认网站中有两个标记为“应用程序”的虚拟目录。一个用于上载目录,我认为与此问题无关,但另一个指向与应用程序主目录相同的物理目录。删除“应用程序名称”似乎已经解决了。我很高兴,但希望我能更好地理解WHY@John很高兴听到你得到了结果。好吧,理解它为什么不难——这就是我对这个问题的预感。当你将一个虚拟文件夹转换为应用程序时,这将创建一个单独的应用程序,在它自己的AppDomain中运行。这就是为什么你uld在各自的AppDomain中查看并行事件。
- 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