Thread timeout

  • Thread starter JeffSinNHUSA via DotNetMonster.com
  • Start date
J

JeffSinNHUSA via DotNetMonster.com

Hi,

I have a long running task that I want to run on a regular basis to do some
db updates. I can't write a windows service because it is being hosted
elsewhere. I want to run this task within my web application - so here is
what I did:

In the global.asax I declared a delegate function and a timer. In the
application start event, I started the timer. I created a method to
respond to the timer event, which creates a new thread and runs the Long
Running Task method:

Private Delegate Function LongRunningTaskTask() As Integer
Private WithEvents ServiceTimer As New System.Timers.Timer(86400000)


Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
ServiceTimer.Start()
End Sub


Private Sub WakeUp(ByVal sender As Object, _
ByVal e As ElapsedEventArgs) Handles ServiceTimer.Elapsed
Try
' Create new thread
Dim AsyncStatePrice As IAsyncResult
' Start the task on a runtime thread asynchronously
Dim AsyncInvokerPrice As New LongRunningTaskTask(AddressOf
LongRunningTaskUpdate)

AsyncStatePrice = AsyncInvokerPrice.BeginInvoke(Nothing,
Nothing)

Dim WaitHandles() As WaitHandle =
{AsyncStatePrice.AsyncWaitHandle}
WaitHandle.WaitAll(WaitHandles)

Catch ex As Exception
'Throw (ex)
End Try
End Sub


The method kicks off fine, but times-out before completion. I want this to
continue running regardless if the person who invoked the application start
event has their browser open or not. Is there a way to increase the
timeout value for the thread through code. I don't want to change the
session timeout for everyone, just this one process. Is there a better
solution?

Thanks
 
W

William F. Robertson, Jr.

It seems you have a long running task, but I don't see where the return
value comes into play.

This might not be the best solution for what you want, but it is something
else to consider. You could use the ThreadPool.QueueUserWorkItem method
that takes a WaitCallBack and an optional object parameter.

ApplicationStart

ThreadPool.QueueUserWorkItem( new WaitCallBack( LongRunningTask ) );

public static void LongRunningTask( object data )
{
//your long running task in here. If you need the user who kicked this off,
you can pass it
//through object data.
}

LongRunningTask will run in a thread from the ThreadPool that .NET
maintains. The timer event also runs from the thread pool. However, this
is a one time, queue this method and run it. It does not have to be a
static (shared) method, but mine typically are. If you need to do something
with the return value, I am sure you could come up with something, or not
even take this approach anyway.

Timers typically are used for recurring tasks, like checking application
state, processing a continuous queue. If you are merely running this task
"on occasion", it probably would be better served using the thread pool.

I just looked and you code is in VB, sorry about my samples.

HTH,

bill
 
J

JeffSinNHUSA via DotNetMonster.com

Well, I tried the ThreadPool.QueueUserWorkItem approach, but it looks like
it terminates the thread after about 30 seconds.


Private WithEvents ServiceTimer As New System.Timers.Timer(600000)

Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
ServiceTimer.Start()
End Sub


Private Sub PricePointsWakeUp(ByVal sender As Object, _
ByVal e As ElapsedEventArgs) Handles ServiceTimer.Elapsed
Dim stateInfo As New TaskInfo("Price Points Update", 1)
If ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf
LongRunningTask), stateInfo) Then

Thread.Sleep(1000)

End If
End Sub

Public Class TaskInfo
Public Boilerplate As String
Public Value As Integer

Public Sub New(ByVal text As String, ByVal number As Integer)
Boilerplate = text
Value = number
End Sub
End Class

Shared Sub LongRunningTask(ByVal stateInfo As Object)

End Sub
 
W

William F. Robertson, Jr.

I did not realize you are wanting to fire your price point method every
600000. I thought you were wanting a queue that you could queue up long
running tasks, and use your timer to clear the queue. You can probably skip
the queue user work item since your timer is called from a thread in the
ThreadPool anyway. My mistake.

How do you know the thread is dying? Is it receiving a
ThreadAbortException. (that means the thread is timing out) or it is a Sql
timeout exception. If a Sql Timeout exception, you could increase the
CommandTimeout on your SqlCommand object.

If you are recieving the ThreadAbortException, you probably will have to
manually create a thread (not from the ThreadPool) to run the long running
task. Your timer shouldn't block waiting for it to complete, but probably
should fire the thread off and then return immediately.

If you need a sample to get a manually created thread off and running let me
know.

Sorry for misunderstanding you and basically giving you the run around. :)

bill
 
J

JeffSinNHUSA via DotNetMonster.com

No problem on the advice - I learned something new.

So back to the old code. I threw try catch blocks around everything, and
instead of throwing an exception, I emailed myself the esception info. I
also email myself as it loops thru the data it is processing. After about
6 iterations (which takes about 60 seconds) I stop receiving emails. Looks
like an exception isn't being thrown.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top