Reputation: 932
A have ASP.NET 2.0 web application that should allow sending emails. I have a windows service that sends emails immediately. My web application composes email message according to some template and put it in MSMQ and the service get it from there.
The problem is that composing message from template can take some time and I don't want user to wait while message is composed and passed to the service.
I think about some background process that will listen internal queue of notifications requests. If queue is empty the process do nothing, but as soon as message appeared it begins to process message. I want to have only a single process to not to create a lot of threads.
Currently my idea is to write task scheduler, that will contain queue of notifications requests. When new item is added to the queue the scheduler checks whether process of sending notifications is running. If yes, then it just add the request to the queue. Otherwise it creates new thread that will read the queue until it is empty and perform notification requests.
My concern is I need to be sure my thread will not die after ASP.NET finish the response to a client because it is parent thread for my thread. And the question is what is the best way to do it (or is it possible to do it)?
P.S. It is ok that my thread dies if IIS recycles ASP.NET process due to user inactivity.
Upvotes: 3
Views: 1284
Reputation: 353
You can create a Web Service, where you can make async calls from your ASP.NET app. The async call will allow you to make calls without blocking the main thread. I think you can do one way calls and don't have to wait for the thread to complete.
Upvotes: 0
Reputation: 9712
I use the class below as a base class. I inherit from this class and put my logic inside it. I then store the instance of this class in the ASP.Net cache so that a reference is kept and I can always find it. For your purposes after inheriting from this class inside of ExecuteProcess create an infinite while loop "while(true)", then put a delay at the top/bottom of the loop "thread.sleep(500)", or something like that. Each loop check for messages in the queue.
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
Upvotes: 1
Reputation: 218827
How about an intermediary service between the site and the Windows service that currently sends the emails? The site can drop the raw data it receives into a queue for the new service, the new service picks it up and composes the message, and drops that into the queue for the windows service which sends the emails. That way the impact on the site and the mail service is minimal, you're just adding another queue to the flow.
The idea you're driving towards is that all data processing which doesn't need to be live should be off-loaded from the live site into a background service (or any number of background services). The site isn't the business logic, it's just a UI for users to interact with the logic engine behind the scenes, of which the services are a part. All the site or any part of the site needs to do is persist the data and go back to responding to user requests.
Upvotes: 1