create a desktop application event schedule using c#

SweetsJamRock
SweetsJamRock used Ask the Experts™
on
Is anyone out their know how to create schedule event using c# in a desktop application.  i would like to send a notice to a few people when a specific date and time is reached automatically from my desktop application
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
IT Consultant
Top Expert 2010
Commented:
Probably the better thing to do would be to use the Windows Task Scheduler, and have it either start your application with a command line argument; or use a separate tiny little program that does nothing other than send the notification and start that. That way you don't need to code any of the timer stuff yourself, and will probably be a little more reliable (e.g. if you do it yourself entirely within your program, then your program needs to be running whereas with the task scheduler you can set it up so that no one even needs to be logged onto the computer).

Author

Commented:
hi genius,

i like your idea about making the task scheduler call the event but how do i go about doing something like that,  and what would i need to do
Todd GerbertIT Consultant
Top Expert 2010

Commented:
One approach is to use a System.Timers.Timer.  You can figure out how many milliseconds there are between Now and the event's scheduled time.  Set the timer's interval to that number of milliseconds, and when the timer's Elapsed event fires run your event.

using System;
using System.Timers;

class Program
{
	// This doesn't apply to your schedule event/timer question
	// I'm just using the ManualResetEvent to force this console
	// application example to wait until the event fires before
	// exiting
	static System.Threading.ManualResetEventSlim wait = new System.Threading.ManualResetEventSlim(false);
	
	static void Main(string[] args)
	{
		// Create a timer
		Timer timer = new Timer();
		// Turn off auto-reset (we only want it to fire once)
		timer.AutoReset = false;
		// Subscribe to it's elapsed event
		timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);

		// Prompt for a date/time
		Console.Write("Enter a date & time (mm/dd/yyyy HH:MM:SS AM/PM): ");
		string scheduleTimeString = Console.ReadLine();

		// Convert the string into a datetime object
		DateTime scheduleTime = DateTime.Parse(scheduleTimeString);

		// Figure out how many milliseconds between now
		// and the event scheduled time
		double millisecondsToWait = (scheduleTime - DateTime.Now).TotalMilliseconds;

		// Set the timer to wait that many milliseconds and start it
		timer.Interval = millisecondsToWait;
		timer.Start();

		Console.Write("Waiting for event scheduled at {0}...", scheduleTime);

		// This just suspends the program until wait.Set() is called
		// in timer_Elapsed()
		wait.Wait();

		Console.Write("Press any key to exit...");
		Console.ReadKey();
	}

	static void timer_Elapsed(object sender, ElapsedEventArgs e)
	{
		Console.WriteLine("\r\nScheduled Event Fired: {0}\r\n", DateTime.Now);
		wait.Set();
	}

}

Open in new window

CompTIA Network+

Prepare for the CompTIA Network+ exam by learning how to troubleshoot, configure, and manage both wired and wireless networks.

Todd GerbertIT Consultant
Top Expert 2010

Commented:
Of course, you can wrap that timer code in a class to make using it simpler:

Use:
static bool exitLoop = false;

static void Main(string[] args)
{
	Console.Write("Enter a date & time (mm/dd/yyyy hh:mm:ss AM/PM): ");
	string eventDateTimeStr = Console.ReadLine();

	ScheduledEvent scheduledEvent = new ScheduledEvent(eventDateTimeStr);
	scheduledEvent.EventFired += new EventHandler(scheduledEvent_EventFired);
	scheduledEvent.Start();

	do
	{
		Console.WriteLine("{0} seconds remaining...", scheduledEvent.TimeRemaining.TotalSeconds);
		System.Threading.Thread.Sleep(999);
	} while (!exitLoop);

	Console.Write("Press any key to exit...");
	Console.ReadKey();
}

static void scheduledEvent_EventFired(object sender, EventArgs e)
{
	Console.WriteLine("\r\nThe event fired at: {0}\r\n", DateTime.Now);
	exitLoop = true;
}

Open in new window


The ScheduledEvent class:
public class ScheduledEvent
{
	private DateTime? _eventTime = null;
	private System.Timers.Timer timer;

	public event EventHandler EventFired;

	public ScheduledEvent()
	{
		timer = new System.Timers.Timer();
		timer.AutoReset = false;
		timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
	}

	public ScheduledEvent(DateTime EventDateTime) : this()
	{
		this.EventDateTime = EventDateTime;
	}

	public ScheduledEvent(string EventDateTimeString) : this()
	{
		DateTime dt;
		if (!DateTime.TryParse(EventDateTimeString, out dt))
			throw new FormatException("EventDateTimeString is not a recognized format for date and time.");
		this.EventDateTime = dt;
	}

	protected virtual void OnEventFired(EventArgs e)
	{
		if (EventFired != null)
			EventFired(this, e);
	}

	public DateTime EventDateTime
	{
		get
		{
			if (!_eventTime.HasValue)
				throw new Exception("The EventDateTime property has not been set.");
			else
				return _eventTime.Value;
		}

		set
		{
			if (value <= DateTime.Now)
				throw new ArgumentException("The EventDateTime value must occur in the future.");
			else
				_eventTime = value;
		}
	}

	public TimeSpan TimeRemaining
	{
		get
		{
			if (!_eventTime.HasValue)
				throw new Exception("The EventDateTime property has not been set.");
			else
				return _eventTime.Value - DateTime.Now;
		}
	}

	public void Start()
	{
		if (_eventTime <= DateTime.Now)
			throw new Exception("The ScheduledEvent's EventDateTime property occurs in the past.");

		double millisecondsToEvent = (_eventTime.Value - DateTime.Now).TotalMilliseconds;
		timer.Interval = millisecondsToEvent;
		timer.Start();
	}

	public void Stop()
	{
		timer.Stop();
	}

	private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
	{
		OnEventFired(new EventArgs());
	}
}

Open in new window

Todd GerbertIT Consultant
Top Expert 2010

Commented:
One other thing...the timer's Elapsed event is raised in a separate thread, which means you'll have problems if you're using the ScheduledEvent in a Forms application, and you try to access parts of the form inside the EventFired event.

The way to solve that problem is to set the SynchronizingObject property of the timer to an object (e.g. a Form for example) so then the Timer's Elapsed (and consequently the ScheduledEvent's EventFired) event will be raised in the same thread the form is in.

This slightly modified ScheduledEvent class just exposes the timer's SynchronizingObject property:

public class ScheduledEvent
{
	private DateTime? _eventTime = null;
	private System.Timers.Timer timer;

	public event EventHandler EventFired;

	public ScheduledEvent()
	{
		timer = new System.Timers.Timer();
		timer.AutoReset = false;
		timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
	}

	public ScheduledEvent(DateTime EventDateTime) : this()
	{
		this.EventDateTime = EventDateTime;
	}

	public ScheduledEvent(string EventDateTimeString) : this()
	{
		DateTime dt;
		if (!DateTime.TryParse(EventDateTimeString, out dt))
			throw new FormatException("EventDateTimeString is not a recognized format for date and time.");
		this.EventDateTime = dt;
	}

	protected virtual void OnEventFired(EventArgs e)
	{
		if (EventFired != null)
			EventFired(this, e);
	}

	public ISynchronizeInvoke SynchronizingObject
	{
		get { return timer.SyncrhonizingObject; }
		set { timer.SynchronizingObject = value; }
	}
	
	public DateTime EventDateTime
	{
		get
		{
			if (!_eventTime.HasValue)
				throw new Exception("The EventDateTime property has not been set.");
			else
				return _eventTime.Value;
		}

		set
		{
			if (value <= DateTime.Now)
				throw new ArgumentException("The EventDateTime value must occur in the future.");
			else
				_eventTime = value;
		}
	}

	public TimeSpan TimeRemaining
	{
		get
		{
			if (!_eventTime.HasValue)
				throw new Exception("The EventDateTime property has not been set.");
			else
				return _eventTime.Value - DateTime.Now;
		}
	}

	public void Start()
	{
		if (_eventTime <= DateTime.Now)
			throw new Exception("The ScheduledEvent's EventDateTime property occurs in the past.");

		double millisecondsToEvent = (_eventTime.Value - DateTime.Now).TotalMilliseconds;
		timer.Interval = millisecondsToEvent;
		timer.Start();
	}

	public void Stop()
	{
		timer.Stop();
	}

	private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
	{
		OnEventFired(new EventArgs());
	}
}

Open in new window


Then you could use it in a form without issue so long as you set the SynchronizingObject property...
public class MyForm : Form
{
	ScheduledEvent schEvent;
	
	public MyForm()
	{
		InitializeComponent();
		schEvent = new ScheduledEvent();
		schEvent.SynchronizingObject = this;
	}
}

Open in new window

Top Expert 2011

Commented:
This project provides a single assembly wrapper for  of Task Scheduler found in all Microsoft operating systems
http://taskscheduler.codeplex.com/
What tasks do you wish to execute..??
Send Mails?
Write Auto Entry To Event Log?
Display Reminders on Time Basis?

For all of the above I would rather go with a windows Service Application with the use of System.Timers.Timer to perform the work activities on timely basis.. Please give me exact requirement so that I can give you the accurate solution to your problem..
Todd GerbertIT Consultant
Top Expert 2010

Commented:
I wouldn't bother writing a service - I think it would make more sense to just use the Windows Task Scheduler.  That link that dj_alik posted (http:#a35762568) looks very promising - no sense re-inventing the wheel!
Navneet.Net Full Stack Developer

Commented:
HI!

1. Create an C# Application to send email etc
2. There is Scheduled Task in Window OS
    Where you can set your application to run
    Either daily, weekly,  every one hour etc.

It's easy to handle as your exe just care about your Business logic.
And With Windiws Scheduler You can enable, disable your exe
and set the time appropriately without worrying.

Thanks!
Todd GerbertIT Consultant
Top Expert 2010

Commented:
@navneethegde

Scheduled Tasks were already suggested - a couple times.
Todd GerbertIT Consultant
Top Expert 2010

Commented:
>> i like your idea about making the task scheduler call the event but how do i go about doing something like that,  and what would i need to do

Sorry, I misread your comment earlier! :)

Write a separate program that does the notification (e.g. sends an e-mail), or write code in your main program to check the command line arguments for something like "/notify" - if the command line argument is present don't really startup, just send notifications. If the command line argument isn't present, startup normally.

In the Control Panel on your computer (and/or in Administrative Tools) you should find "Scheduled Tasks" or "Task Scheduler" which will let you schedule your notification program to run on a schedule - e.g. on 5/30/2011 at 9:00 AM; or every Tuesday at 5:00 PM; or every 15 minutes (it's pretty flexible).

If you want to be able to setup the schedule from within your program (i.e. so that someone using your program doesn't have to setup the schedule themselves, the program will do it for them), take a look at dj_alik's excellent comment: http:#a35762568

Author

Commented:
Starlitt551,
I was told creating a windows service which seem to be the right way to go. The reminder is trigger via date from a table. Give how I would use a service to deal with this

Todd GerbertIT Consultant
Top Expert 2010
Commented:
You can refer to my earlier comments concerning how to code a timer yourself (whether the code runs in a service, a console application, or a forms application is largely irrelevant - just keep in mind a service can't interact with the logged-on user, e.g. showing a message box from a service is not really possible).

However, it just seems silly to me to write a scheduling service from scratch yourself when there's already one built into Windows that's ready-to-use. What benefit do you see to writing your own service as opposed to using the task scheduler?

Author

Commented:
all of you guys have given me an idea how to approach what i want to do.  thanks much

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial