Thanks
The key/trick is that you can have a timer... which fires and does the work.
The timer has a "dueTime" and "intervalTime". By manipulating these values.
you can get the service to fire once a night.
But you'll have to do a little math.
Lets say you want it to start at midnight.
But the windows service "starts up" at 4:10 pm (whenever the computer
reboots or etc)
So you have to do some math to say "I need to dueTime to be in 7hrs and 50
minutes"
(midnight subtract the current time of 4:10pm)
Then you can set the interval to 24 hours.
That way.... it will always fire at midnight....
That's ~a way. I don't know if its the best way.
Here is some code. Its from way back, and in vb.net. Before my company's
conversion. But should give you an idea.
#1 Here is the xml I 'm using. Notice that 86400000 is the number of ms in 1
day.
<?xml version="1.0"?>
<root>
<data>
<services>
<service nameof="beep" active="1" interval_milliseconds="12000"
start_time=""/>
<service nameof="my_service_name" active="1"
interval_milliseconds="86400000" start_time="4:09 PM"/>
</services>
</data>
</root>
Here is the class to do the math...... based on the XML.
Public Class FeaturesEnabled
Private xmlDoc As New System.Xml.XmlDocument()
Private boolBeepServiceIsEnabled As Boolean
Private lngBeepServiceIntervalMilliseconds As Long
Public Function GetDueTime(ByVal strServiceName As String) As Long
Const LNG_DEFAULT_DUE_TIME As Long = 30000
Dim t1 As DateTime
Dim t2 As DateTime
Dim lngMinutesDifference As Long
Dim lngDueTime As Long
Dim strCurrentServiceStartTime As String
Select Case strServiceName
Case "my_service_name"
' (this special call will set the service to run at an EXACT Time, instead
of
' when the the main monitoring service is started ..
' this is Good for long running procedures.
'THIS IS A SPECIAL CASE BECAUSE my_service_name is such a long running
procedure to be done offhours
'That It NEEDS to start at a specific time (an OFF HOURS TIME)
'get the TIME from the xml
strCurrentServiceStartTime =
(xmlDoc.SelectSingleNode("//root/data/services/service[@nameof='" &
strServiceName & "']/@start_time").Value)
If Len(strCurrentServiceStartTime) <= 0 Then
'default safety
strCurrentServiceStartTime = "12:00 AM"
End If
t2 = Date.Now
t1 = CDate(Date.Today.ToShortDateString & " " & strCurrentServiceStartTime)
lngMinutesDifference = (DateDiff(DateInterval.Minute, t2, t1))
If lngMinutesDifference > 0 Then
lngDueTime = lngMinutesDifference * 60 * 1000 ' take the minues and do the
math to get the milliseconds
ElseIf lngMinutesDifference < 0 Then
' the next line will set the delay time to the NEXT occurence of the time
lngDueTime = ((24 * 60) - lngMinutesDifference) * 60 * 1000
Else
lngDueTime = 0
End If
GetDueTime = lngDueTime
EventLogWriter.WriteEventLogEntry(UCase(strServiceName) & " DELAY period set
to : " & lngDueTime & vbCrLf & (lngDueTime / (1000 * 60 * 60)) & " hours" &
vbCrLf & vbCrLf & t1.ToString & vbCrLf & t2.ToString,
EventLogEntryType.Information)
Case Else
GetDueTime = LNG_DEFAULT_DUE_TIME
End Select
End Function
Public Function GetBeepServiceIntervalInMilliSeconds()
GetBeepServiceIntervalInMilliSeconds = lngBeepServiceIntervalMilliseconds
End Function
Public Function GetBeepServiceIsEnabled() As Boolean
GetBeepServiceIsEnabled = boolBeepServiceIsEnabled
End Function
Public Sub New()
'some default values
lngBeepServiceIntervalMilliseconds = 3000
Dim strCompletePathFileXMLFileName As String
strCompletePathFileXMLFileName = ( find the xml file some how )
xmlDoc.Load(strCompletePathFileXMLFileName)
boolBeepServiceIsEnabled =
((xmlDoc.SelectSingleNode("//root/data/services/service[@nameof='beep']/@act
ive").Value) <> 0)
Try
lngBeepServiceIntervalMilliseconds =
(xmlDoc.SelectSingleNode("//root/data/services/service[@nameof='beep']/@inte
rval_milliseconds").Value)
Catch
'Just use defaults if anything fails, aka, no "catching" (aka, see its
declaration above)
End Try
End Sub
End Class
Finally:::::::::::::::::::
This code is what wires up some method ... to when the timer fires.
/*
//'Member Variables
Private feFeaturesEnabled As FeaturesEnabled ' used to encapsulate which
"services inside of this main service" are running
Private timBeepServiceTimer As Timer
*/
Private Sub BeepSetup()
Dim lngDueTime As Long
Dim lngPeriod As Long
' DUE TIME looks like it is the DELAY time .. from the time the service
starts,
' Until this specfic TIMER kicks in. So a Delay Time of 20000
' Will DELAY this timer shooting off until 20 seconds (20000 ms) after the
service starts
lngDueTime = feFeaturesEnabled.GetDueTime("")
lngPeriod = feFeaturesEnabled.GetBeepServiceIntervalInMilliSeconds()
' the magic bullet, notice the part after "AddressOf", which is the method
Dim timerDelegate = New TimerCallback(AddressOf BeepClass.GoBeep) ''
BeepClass.GoBeep is a class with a static/shared method "GoBeep". Here you
would your msmq listener.
timBeepServiceTimer = New Timer(timerDelegate, Me, lngDueTime, lngPeriod) ''
so you're saying... I want to time to start at midnight (using the
calculated dueTime and period ......
End Sub
I think even thru the average vb.net code what is going on.
Outside of coding up the EventHandler's (AddressOf vs += new
EventHandler() ).. the translation should be easy enough.
Here is the simple BeepClass
Public Class BeepClass
Public Shared Sub GoBeep(ByVal state As Object)
Beep()
End Sub
End Class
Check out
http://msmvps.com/blogs/manoj/archive/2005/10/16/70979.aspx
for a good async msmq processor.
<mjp...@gmail.com> wrote in message
news:1156440738.7...@b28g2000cwb.googlegroups.com...
Just call Receive() within a loop to process the messages one at a time and
use TimeSpan to specify a time limit of some arbitrary amount (say 1
second). When the Receive call throws an IOTimeout exception you can assume
the queue is empty and so you have processed all the messages in the queue.
For example
static void Main(string[] args)
{
MessageQueue queue = new MessageQueue(@".\testQueue");
// set up other queue attributes as necessary
System.Messaging.Message msg = null;
try
{
while (true)
{
msg = queue.Receive(new TimeSpan(0, 0, 1));
// process msg contents
}
}
catch (MessageQueueException mqe)
{
if (mqe.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout)
{
// Do nothing queue is just empty
}
else
{
// unexpected exception
throw;
}
}
}