Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET background worker thread

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.

like image 221
lostaman Avatar asked Jun 23 '26 06:06

lostaman


1 Answers

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
like image 68
Peter Avatar answered Jun 25 '26 19:06

Peter



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!