threading

P

Perecli Manole

I have a background worker thread that receives queued work items and
processes them. How do I make this background thread go in a sleep state
while the queue is empty and then wake back up as soon as there are work
items to be performed?

To much processor time is being wasted right now checking an empty queue in
a loop.

Thanks
Perry
 
A

Armin Zingler

Perecli Manole said:
I have a background worker thread that receives queued work items
and processes them. How do I make this background thread go in a
sleep state while the queue is empty and then wake back up as soon as
there are work items to be performed?

To much processor time is being wasted right now checking an empty
queue in a loop.

Can you add Thread.Sleep(100) inside the loop?
 
J

Jay B. Harlow [MVP - Outlook]

Perecli,
In addition to Armin's suggestion. I normally use a
System.Threading.AutoResetEvent along with the queue. Depending on the
parameters you pass to the AutoResetEvent.WaitOne method, the background
thread will sleep indefinitely waiting for the event to be signaled.

The background thread has two loops. The outer loop does an
AutoResetEvent.WaitOne waiting for the event to be signaled. When the event
is signaled the background thread has an inner loop processing each item in
the queue.

When other threads put work items into the queue they Set the above
AutoResetEvent, letting the background thread know there is at least one
item in the queue.

Normally I put the Thread, the AutoResetEvent, the Queue and the padlock for
the Queue into a single class that represents the "Worker". Encapsulating
the above into clean type safe methods.

Hope this helps
Jay
 
F

Fergus Cooney

Hi Perry,

You'd have your Thread sleep when it has finished. Whenever the Queue
receives another Job, it would check the Thread. If it's asleep, you can send
an interrupt. This will cause an Exception which must be caught. [Don't send
the Interrupt if the Thread is not asleep - the Interrupt will hang around
until it <does> go to sleep and then wake it up immediately!!]

Something like the following:

Regards,
Fergus

<code>
In Queue:
oThread As Thread

Sub NewJob (..)
'Add Job to Queue
: : :
If oThread.ThreadState = ThreadState.WaitSleepJoin Then
oThread.Interrupt 'Hey!! Sleepy Head! - I've a job for you.
End If
End Sub

Sub FinishTheJobAndGoHome(..)
While oThread.ThreadState <> ThreadState.WaitSleepJoin
Thread.Sleep (SomeDelay)
End While
oThread.Abort.
oThread.Join.
End Sub

In Worker
Try
Do
'Busy, busy
: : :
If NoMoreJobs Then
'Done for now
Try
Thread.Sleep (Inifinite) 'ZZZzzzz....
Catch e As ThreadInterruptedException
'Yawn, .. streeeetch,... better get back to work.
End Try
Loop
Catch e As ThreadAbortException
'Hurray - knocking off time!!
End Try
</code>
 
P

Perecli Manole

It seems like the AutoResetEvent is the best approach.

I don't understand the padlock element you speak of.
Right now I have something like this but want to get rid of Sleep():

Public Sub SubmitCmd(ByVal objCommand As ICmdExecute)
If Not m_objBgThread Is Nothing Then
SyncLock m_objCmdQueue.SyncRoot
m_objCmdQueue.Enqueue(objCommand)
End SyncLock
End If
End Sub

Private Sub BackgroundThread()
Dim objCommand As ICmdExecute

While True
'dequeue all available commands
Do
SyncLock m_objCmdQueue.SyncRoot
If m_objCmdQueue.Count > 0 Then
objCommand = m_objCmdQueue.Dequeue()
End If
End SyncLock

If objCommand Is Nothing Then
Exit Do
Else
objCommand.Execute()
objCommand = Nothing
End If
Loop

Thread.Sleep(50) 'prevents hoggin up all the CPU's time
End While
End Sub

Should the AutoResetEvent.Set be within the synclock block or out?
What if the AutoResetEvent.Set is executed right before the background
thread is about to call AutoResetEvent.WaitOne? This could halt the
background thread indefinitely even though there are queued items.

Thanks
Perry
 

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

Top