有一个ASP.NET 2.0 Web应用程序,应该允许发送电子邮件。我有一个Windows服务,可以立即发送电子邮件。我的Web应用程序根据某个模板编写电子邮件消息并将其放在MSMQ中,服务从那里获取。
问题是从模板编写消息可能需要一些时间,我不希望用户在编写消息并将其传递给服务时等待。
我想一些会监听通知请求内部队列的后台进程。如果队列为空,则进程不执行任何操作,但只要消息出现,它就会开始处理消息。我想只有一个进程来不创建很多线程。
目前我的想法是编写任务调度程序,它将包含通知请求队列。将新项目添加到队列时,调度程序会检查发送通知的进程是否正在运行。如果是,那么它只是将请求添加到队列中。否则,它会创建新线程,该线程将读取队列,直到它为空并执行通知请求。
我担心的是我需要确保我的线程在ASP.NET完成对客户端的响应后不会死,因为它是我的线程的父线程。问题是最好的方法是什么(或者可以做到这一点)?
P.S。如果由于用户不活动而导致IIS回收ASP.NET进程,我的线程就会死掉。
答案 0 :(得分:1)
网站与当前发送电子邮件的Windows服务之间的中间服务如何?该站点可以将收到的原始数据丢弃到新服务的队列中,新服务将其拾取并编写消息,然后将其放入发送电子邮件的Windows服务的队列中。这样,对网站和邮件服务的影响很小,您只需在流中添加另一个队列。
您正在努力的想法是,所有不需要生效的数据处理应该从实际站点卸载到后台服务(或任意数量的后台服务) )。该站点不是业务逻辑,它只是用户与幕后逻辑引擎交互的UI,其中服务是其中的一部分。站点或站点的任何部分需要做的就是保留数据并返回响应用户请求。
答案 1 :(得分:1)
我使用下面的类作为基类。我从这个类继承并将我的逻辑放在其中。然后,我将此类的实例存储在ASP.Net缓存中,以便保留引用,并且我总能找到它。为了你的目的,在继承ExecuteProcess中的这个类之后创建一个无限的while循环“while(true)”,然后在循环“thread.sleep(500)”的顶部/底部加一个延迟,或类似的东西。每个循环都检查队列中的消息。
Imports System.Threading
Public MustInherit Class LongRunningProcess
Public ReadOnly Property Running() As Boolean
Get
Return _Running
End Get
End Property
Public ReadOnly Property Success() As Boolean
Get
Return _Success
End Get
End Property
Public ReadOnly Property Exception() As Exception
Get
Return _Exception
End Get
End Property
Public ReadOnly Property StartTime() As DateTime
Get
Return _StartTime
End Get
End Property
Public ReadOnly Property EndTime() As DateTime
Get
Return _EndTime
End Get
End Property
Public ReadOnly Property Args() As Object
Get
Return _Args
End Get
End Property
Protected _Running As Boolean = False
Protected _Success As Boolean = False
Protected _Exception As Exception = Nothing
Protected _StartTime As DateTime = DateTime.MinValue
Protected _EndTime As DateTime = DateTime.MinValue
Protected _Args() As Object = Nothing
Protected WithEvents _Thread As Thread
Private _locker As New Object()
Public Sub Execute(ByVal Arguments As Object)
SyncLock (_locker)
'if the process is not running, then...'
If Not _Running Then
'Set running to true'
_Running = True
'Set start time to now'
_StartTime = DateTime.Now
'set arguments'
_Args = Arguments
'Prepare to process in a new thread'
_Thread = New Thread(New ThreadStart(AddressOf ExecuteProcess))
'Start the thread'
_Thread.Start()
End If
End SyncLock
End Sub
Protected MustOverride Sub ExecuteProcess()
End Class
答案 2 :(得分:0)
您可以创建一个Web服务,您可以在其中从ASP.NET应用程序进行异步调用。异步调用将允许您在不阻塞主线程的情况下进行调用。我认为你可以做单向调用,而不必等待线程完成。