简体   繁体   中英

Best way to schedule messages to be sent using a Windows service in C#

I'll try and briefy explain what i'm looking to achieve. My intial idea of doing this, is not going to work well in my opinion, so i'm trying to decide how best to plan this.

The first thought was:

I have a list of messages that need to be sent out at scheduled times, each one is stored in a central SQL database.

The intention is to use a Windows service that will have a timer that ticks every 30 mins. So..

30 Mins pass > Call ScheduleMessages()

ScheduleMessages will check the database for any unsent messages that need to go out in the next 30 minutes, it will then mark them in the database as:

ScheduleActivated = 1

For each one it marks as ScheduleActivated = 1 it will fire off a customer time object which inherits from the normal timer, which also includes the properties for the message it needs to send.

It will be set to tick at the time the message is due to go out, will send the message and mark as successful in the database.

The main problem with this is I am going to have timers all over the place, and if there were a few hundred messages sheduled at once, it's probably going to either not perform well, or fall over completely.

After re-evalutating I thought of solution 2

My other idea was to have 1 timer running in the service, which ticks once every 10 minutes. Each time it ticks it would fire off a method that gathers every single message due to be sent at any point up until that time into a list, and then processes them one at a time.

This seems much less resource intensive, but i'm worried that if the timer ticks after 10 minutes, any messages that haven't finished sending, wil be caught in the next tick, and be sent again.

Would it be work to stop the timer once it has been going for 10 minutes, then reset to zero and start again once the messages have been sent.

Is there a 3rd solution to the problem which is better than the above?

We implemented this on one project, what worked for us was:

  • All messages written to a table with a send time
  • Service that checks every x mins if there is something to send
  • When the service sends a message it also marks the message a sent (update sent time from null to actual sent time)

Marking the message avoids resends, and if you want to resend you just set the date to null.

The only problem that we had is that the service ran as a single thread and the number of messages sent was therefore limited. But you would have very many messages and a very small window before this is a problem.

Ditch the fixed interval. Windows has plenty of ways to sleep for a specific amount of time, including the sleep function, waitable timers, etc.

Some of these are available in .NET, for example WaitHandle.WaitAll accepts a sleep time and an event, that way your thread can wait until the next scheduled item but also be woken by a request to modify the schedule.

In my opinion, the scheduling service should only be responsible for checking schedules and any work should be passed off to a separate service. The scheduling service shouldnt care about the work to be scheduled. Try implementing a work item interface that contains an execute method. That way the executing object can handle the internals itself and neednt be aware of the scheduling service. For scheduling have you checked out quartz.net?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM