Lets suppose I have a single class that has two methods OnBarEvent & Update.
Update: subscribes to a continuous stream of data that comes in asynchronously.
OnBarEvent: will send an event out every n minutes. I am using a timer class to keep track of time and then just have SendEvent attached to the timer class event handler. Essentially, this method will be called whenever N minutes pass
The program will receive asynchronous data via OnEvent which will just summarize the data over a period of time. Once a specified time has passed, then the SendEvent will be called
namespace Common.Aggregator
{
public class BaseTimeAggregator
{
//The last time we emitted a consolidated bar
private DateTime? _lastEmit;
//The minimum timespan between creating new bars.
private readonly TimeSpan? _period;
//The working bar used for aggregating the data
private Bar _workingBar;
//The last working bar
private Bar l_workingBar;
//The Start Time
private DateTime StartTime;
private System.Timers.Timer timer;
public new event EventHandler<Bar> DataConsolidated;
private void OnBarEvent(Object source, System.Timers.ElapsedEventArgs e)
{
if (DateTime.Now > StartTime)
{
if (_workingBar != null)
{
//Console.WriteLine("New Bar: {0}", e.SignalTime);
lock (_workingBar)
{
// Fire Bar
var workingTradeBar = _workingBar as Bar;
if(l_workingBar == null)
{
decimal close_ret = workingTradeBar.Close / workingTradeBar.PreClosePrice;
workingTradeBar.Logret = (decimal)Math.Log((double)close_ret);
}
else
{
// PROBLEM: workingTradeBar can be null here for some reason
decimal value = workingTradeBar.Close / l_workingBar.Close;
workingTradeBar.Logret = (decimal) Math.Log((double)value);
}
l_workingBar = workingTradeBar;
DataConsolidated(this, workingTradeBar);
_workingBar = null;
}
}
}
}
public void Update(Tick data)
{
AggregateBar(data);
}
protected void AggregateBar(Tick data)
{
// Create New Bar
if (_workingBar == null)
{
_workingBar = new Bar(data.LastPrice, data.LastPrice, data.LastPrice, data.LastPrice);
_workingBar.PreClosePrice = data.PreClosePrice;
}
lock (_workingBar)
{
// In the case it got accessed in between
if (_workingBar == null)
{
_workingBar = new Bar(data.LastPrice, data.LastPrice, data.LastPrice, data.LastPrice);
_workingBar.PreClosePrice = data.PreClosePrice;
}
// Update Bar
_workingBar.Update(data.DataType, data.LastPrice, data.BidPrice, data.AskPrice,
data.Volume, data.BidSize, data.AskSize);
}
}
return new DateTime(
dateTime.Year,
dateTime.Month,
dateTime.Day,
hours,
minutes,
seconds,
milliseconds,
dateTime.Kind);
}
}
}
The problem I am running in to is that within the lock, when I access the workingTradeBar variable (see commented code above where "PROBLEM"), there are situations where its null and throws a system.null error. I can't figure out how it can be null given I made a check right before I entered the lock. Also, the only place I set it null is in the same method since I want to start summarizing the data after N minutes passed.
Thanks
This is different from the other question because its purely a multi-threading problem/race condition.
Some remarks:
Event handlers should get the current instance from input params, not from the local variable.
If required need store references to all Bars.
Any method that manipulates the Bars should be synchronized.
As alternative the lock-statement can be used ReaderWriterLockSlim.
namespace Common.Aggregator
{
public class BaseTimeAggregator
{
// REMOVE this field
// --> private Bar _workingBar;
private readonly object _lock = new object();
private readonly Dictionary<int, Bar> _barDictionary = new Dictionary<int, Bar>();
private void OnBarEvent(Object source, System.Timers.ElapsedEventArgs e)
{
var bar = (Bar)source;
// Manipulate with the actual instance defined in 'bar'-variable ..
}
public void Update(Tick data)
{
lock (_lock) {
AggregateBar(data);
}
}
public void Smth_method(int barId)
{
lock (_lock) {
var bar = _barDictionary[uniqueBarId];
// ..
}
}
protected void AggregateBar(Tick data)
{
var uniqueBarId = data.{some param that identify bar};
if (_barDictionary.ContainsKey(uniqueBarId)) {
_barDictionary[uniqueBarId].Update(data.DataType, data.LastPrice, data.BidPrice, data.AskPrice, data.Volume, data.BidSize, data.AskSize);
return;
}
var bar = new Bar(data.LastPrice, data.LastPrice, data.LastPrice, data.LastPrice);
bar.PreClosePrice = data.PreClosePrice;
_barDictionary[uniqueBarId] = bar;
}
}
}
Related
I'm trying to do a notification system that will popup every exact defined minute.
I'm using Tulpep.NotificationWindow from Nuggets but i have a problem with it, it won`t pop up the notification, but works as a messagebox instead of Tulpep.NotificationWindow.
My code:
namespace SpawnBosi
{
public partial class Form1 : Form
{
Thread t1;
int channel1 = 46;
int result;
public Form1()
{
InitializeComponent();
t1 = new Thread(new ThreadStart(checkforminutes));
t1.Start();
}
public void checkforminutes()
{
while (true)
{
result = DateTime.Now.Minute;
compareminutes();
}
}
public void Ch1Notificaton()
{
var popupNotifier = new PopupNotifier();
popupNotifier.TitleText = "Title of popup";
popupNotifier.ContentText = "Content text";
popupNotifier.IsRightToLeft = false;
popupNotifier.Popup();
}
public void compareminutes()
{
if (result == channel1)
{
Ch1Notificaton();
}
}
}
}
Thread t1 will check every second if the minute changed and will compare the channel1 with actual DateTime.Now.Minute.
if the time is == with channel1 set time should notify . But it donesn't work with this system. How can i resolve my problem?
UPDATE
int channel1 = 25;
int channel2 = 26;
public Form1()
{
InitializeComponent();
}
public void checkandcompareminutes()
{
int actualminute = DateTime.Now.Minute;
if (actualminute == channel1 || actualminute == channel2)
{
Ch1Notificaton();
}
}
public void Ch1Notificaton()
{
var popupNotifier = new PopupNotifier();
popupNotifier.TitleText = "Title of popup";
popupNotifier.ContentText = "Content text";
popupNotifier.IsRightToLeft = false;
popupNotifier.Popup();
}
private void timer1_Tick(object sender, EventArgs e)
{
checkandcompareminutes();
}
}
There are a lot of things I would change here:
You do not need to use the object variable result. Use a local variable and combine the code of checkforminutes and compareminutes to one method.
You should use a Thread.Sleep to wait at least e.g. 500 milliseconds in your while-loop. This loop is quite exhaustive in regards to CPU time.
Overall you should better use the Timer class instead of checking the time in a while-loop.
Iv'e created a timer using dispatcher time :
time = new DispatcherTimer();
time.Interval = new TimeSpan(0, 0, 0, 0, 80);
and I use it for the speed of an object.Each tick the objects moves 10 pixels.
I would like to know how to increase the speed of the object without changing the pixels it moves each tick, meaning I want to make the timer itself faster during run time every 10 seconds or so.
Is there a way I can do it?Ive tried making a variable speed=0 and increasing it each time I count 10 and then
time.Interval = new TimeSpan(0, 0, 0, 0, 80-speed);
but The object stayed in the same speed.So do I have to make my own timer class instead of using the built in dispatcher time, if so how do I do that?or is there another solution for this?
I think that DispatcherTimer is not your best ally for this task. The class is by no means designed to execute actions at precise intervals.
I'll try to better explain myself: even if the DispatcherTimer, as its name suggests, dispatches actions timely and with a great precision, the dispatched actions will be queued and then executed when the underlying GUI thread decides to process them.
Normally, a GUI thread has a resolution of around 8ms (it's an approximation, but I don't think we need to measure this right now)... and you are using a starting Interval of 80ms that is going to decrease over time until it probably goes beyond that tolerance limit of 8ms or so. In the meanwhile, you are also repainting your interface (or part of it) over and over and this impacts the performance and the responsiveness of the GUI even more: if the GUI thread is busy repainting and that requires more than the Interval value to be accomplished, the next dispatched action will be processed only once the GUI thread completes the undergoing task.
If you need a more precise scheduling, avoiding hangings / losses of responsiveness / delayed actions, you need to use a timer class that runs in background like System.Threading.Timer (google for SyncronizationContext, that would be helpful) or System.Timers.Timer.
On the top of that, never play with intervals when showing a change in speed. Work with a fixed interval and increase/decrease the movement "size" in pixels. You should be able to calculate the delta without problems. Just to make things clearer: if I want to slow that the speed of an object doubled, I don't half the timer interval that draws the object, but I double the amount of pixels my object traverses at each step.
using System;
using System.Collections.Generic;
using System.Linq;
namespace CQRS_and_EventSourcing
{
internal class Program
{
//CQRS = command query responsibility segregation
//CQS= command query separation
//COMMAND
public class PersonStroge
{
Dictionary<int, Person> people;
}
public class Person
{
public int UniqueId;
public int age;
EventBroker broker;
public Person(EventBroker broker)
{
this.broker = broker;
broker.Commands += BrokerOnCommands;
broker.Queries += BrokeronQueries;
}
private void BrokeronQueries(object sender, Query query)
{
var ac = query as AgeQuery;
if (ac != null && ac.Target == this)
{
ac.Result = age;
}
}
private void BrokerOnCommands(object sender, Command command)
{
var cac = command as ChangeAgeCommand;
if (cac != null && cac.Target == this)
{
if (cac.Register)
broker.AllEvents.Add(new AgeChangedEvent(this, age, cac.Age));
age = cac.Age;
}
}
public bool CanVote => age >= 16;
}
public class EventBroker
{
//1. All events that happened.
public IList<Event> AllEvents = new List<Event>();
//2. Commands
public event EventHandler<Command> Commands;
//3. Query
public event EventHandler<Query> Queries;
public void Command(Command c)
{
Commands?.Invoke(this, c);
}
public T Query<T>(Query q)
{
Queries?.Invoke(this, q);
return (T)q.Result;
}
public void UndoLast()
{
var e = AllEvents.LastOrDefault();
var ac = e as AgeChangedEvent;
if (ac != null)
{
Command(new ChangeAgeCommand(ac.Target, ac.OldValue) { Register = false });
AllEvents.Remove(e);
}
}
}
public class Query
{
public object Result;
}
public class AgeQuery : Query
{
public Person Target;
}
public class Command : EventArgs
{
public bool Register = true;
}
public class ChangeAgeCommand : Command
{
public Person Target;
//public int TargetId;
public int Age;
public ChangeAgeCommand(Person target, int age)
{
Target = target;
Age = age;
}
}
public class Event
{
//backtrack
}
public class AgeChangedEvent : Event
{
public Person Target;
public int OldValue, NewValue;
public AgeChangedEvent(Person target, int oldValue, int newValue)
{
Target = target;
OldValue = oldValue;
NewValue = newValue;
}
public override string ToString()
{
return $"Age changed from {OldValue} to {NewValue}";
}
}
static void Main(string[] args)
{
var eb = new EventBroker();
var p = new Person(eb);
eb.Command(new ChangeAgeCommand(p, 123));
foreach (var e in eb.AllEvents)
{
Console.WriteLine(e);
}
//int age;
//age = eb.Query<int>(new AgeQuery { Target = p });
//Console.WriteLine(age);
//eb.UndoLast();
//foreach (var e in eb.AllEvents)
//{
// Console.WriteLine(e);
//}
//age = eb.Query<int>(new AgeQuery { Target = p });
//Console.WriteLine(age);
Console.ReadKey();
}
}
}
İf you couldnt make look at this repository;
[1]:https://github.com/kYasinAblay/DNesteruk.Additional.Lectures/blob/master/CQRS_and_EventSourcing/Program.cs
I have an issue with data seemingly being reset to its default values.
The class is as follows (objectIDs is a simple enumeration):
public class Output_args: EventArgs {
public objectIDs outputtype;
public int internalID;
public int verdict;
public int outputID;
public long entrytime;
public Output_args Copy() {
Output_args args = new Output_args();
args.entrytime = this.entrytime;
args.internalID = this.internalID;
args.outputID = this.outputID;
args.outputtype = this.outputtype;
args.verdict = this.verdict;
return args;
}
}
The following code creates the object. It runs in a specific thread, let's say Thread1.
class Class1 {
EventWaitHandle ewh = new EventWaitHandle(false, EventResetMode.AutoReset);
public event EventHandler<Output_args> newOutput;
public void readInput(){
List<Output_args> newoutputlist = new List<Output_args>();
/*
* code to determine the outputs
*/
Output_args args = new Output_args();
args.outputtype = objectIDs.stepID;
args.internalID = step[s].ID;
args.verdict = verdict;
args.entrytime = System.DateTime.Now.Ticks;
newoutputlist.Add(args.Copy());
if (newOutput != null && newoutputlist.Count > 0) {
// several outputs are being sent sequentially but for simplicity i've removed the for-loop and decision tree
try {
newOutput(null, newoutputlist[0].Copy());
} catch (Exception) { }
}
}
}
1 of the subscribers to this event has the following code. The processor method runs on a thread of a camerafeed. The newOutput event handler is being run on Thread1.
class Class2: Form {
private Output_args lastoutput = new Output_args();
public void newOutput(object sender, Output_args args) {
lock (lastoutput) {
lastoutput = args.Copy();
}
}
public void processor(){
lock (lastoutput) {
if (lastoutput.entrytime + 10000000 > System.DateTime.Now.Ticks) {
// do something
}
}
}
}
When the eventhandler 'newOutput' of Class2 is being called, the debugger shows that the copy works as expected and 'entrytime' is given the expected number of ticks.
However, when the processor method wants to read the 'entrytime', its value is 0. All other fields also have their default value assigned.
I've tried replacing the object 'lastoutput' with a simple field of the type long and removed the locks but the results are the same: it gets assigned properly in 'newOutput' but has its default value (0) in the processor method.
Any ideas on why this is happening?
you should not lock on the object lastoutput, but on another object, because you reassign the field.
The processor start and lock on the default field instance new Output_args() initialized with default values
class Class2: Form {
private object mylock = new object();
private Output_args lastoutput;
public void newOutput(object sender, Output_args args) {
lock (mylock) {
lastoutput = args.Copy();
}
}
public void processor(){
lock (mylock) {
if (lastoutput == null) {
//nothing to consume yet
}
else if (lastoutput.entrytime + 10000000 > System.DateTime.Now.Ticks) {
// do something
}
}
}
}
but this discard lastouput if consumer is slower than producer. You can use a queue ( or another collection ) as buffer if needed.
class Class2 {
private Queue<Output_args> outputs = new Queue<Output_args>();
public void newOutput(object sender, Output_args args) {
lock (outputs) {
outputs.Enqueue(args.Copy());
}
}
public void processor(){
lock (outputs) {
if (outputs.Count > 0) {
var lastoutput = outputs.Dequeue();
if (lastoutput.entrytime + 10000000 > System.DateTime.Now.Ticks) {
// do something
}
}
}
}
}
demo: https://dotnetfiddle.net/daHVD1
I am trying to create a thread which will continuously check for changes to a value, then visually show that change in a PictureBox located in my GUI.
What I actually wrote is a bit more complicated, so I simplified it while keeping the basic idea, I would be happy to provide clarification if this isn't enough:
public class CheckPictures
{
PictureBox update;
List<String> check;
public CheckPictures(PictureBox anUpdate, List<String> aCheck)
{
update = anUpdate;
check = aCheck;
}
public void start()
{
while(true)
{
if (aCheck[0] == "Me")
{
update.Image = Image.fromFile("");
}
}
}
}
static int Main(string[] args)
{
List<String> picturesList = new List<String>();
CheckPictures thread1 = new CheckPictures(PictureBox1, picturesList);
Thread oThread1 = new Thread(thread1.start));
}
What I want it to do is dynamically change the picture in PictureBox1 if I were to add the string "Me" to pictureList. The above code isn't working like I'd hoped. I had thought that by passing the actual PictureBox and List, any changes to the List elsewhere is the program would be caught by the thread. So my first question is: Is this possible? And if so, what change would I need to make to my code to achieve it?
You might want to use events. You register an eventhandler and when something changes in one thread it calls an event handler in the other to do the work. Busy waiting wastes cpu.
You definetely do not want to do an infinite loop, this will just consume cpu:
while(true)
{
if (aCheck[0] == "Me")
{
update.Image = Image.fromFile("");
}
}
I think you should look into the CountdownLatch class.
public class CountdownLatch
{
private int m_remain;
private EventWaitHandle m_event;
public CountdownLatch(int count)
{
m_remain = count;
m_event = new ManualResetEvent(false);
}
public void Signal()
{
// The last thread to signal also sets the event.
if (Interlocked.Decrement(ref m_remain) == 0)
m_event.Set();
}
public void Wait()
{
m_event.WaitOne();
}
}
The basic idea here is that you need to stop execution on your thread for some time and resume whenever a certain condition has been met (perhaps on another thread).
In other words, you will have a counter, decrement its value on certain condition and whenever it goes to zero you fire your event, execute some code and then start over (stop execution and wait for the counter to go to zero).
In your case you could set the counter to 1 and decrement its value whenever you've set aCheck[0] = "Me"; This way you don't waste CPU.
Pseudo code:
Initialize counter:
CountdownLatch latch = new CountdownLatch(1);
Make thread wait:
public void start()
{
while(true)
{
latch.Wait(); //execution stops
{
//execution resumes once the latch counter is zero.
if (aCheck[0] == "Me") //double check you have what you need
{
update.Image = Image.fromFile("");
latch = new CountdownLatch(1); //reset if you need to do it again
}
}
}
}
Whenever your condition is met (i.e. aCheck[0] = "Me";) signal your latch:
latch.Signal();
this last line will make the thread resume execution. Good stuff.
Create some object, which will raise event, when new picture was added. E.g. class representing pictures collection:
public class PicturesCollection
{
public event EventHandler<PictureAddedEventArgs> PictureAdded;
private List<string> _pictures = new List<string>();
public void Add(string name)
{
_pictures.Add(name);
if (PictureAdded != null)
PictureAdded(this, new PictureAddedEventArgs(name));
}
public IEnumerable<string> Pictures
{
get { return _pictures; }
}
}
If you want to provide some additional data to event, create custom EventArgs:
public class PictureAddedEventArgs : EventArgs
{
public PictureAddedEventArgs(string name)
{
Name = name;
}
public string Name { get; private set; }
}
All you need now - create pictures collection and subscribe to that event:
static int Main(string[] args)
{
PicturesCollection pictures = new PicturesCollection();
pictures.PictureAdded += Pictures_PictureAdded;
}
static void Pictures_PictureAdded(object sender, PictureAddedEventArgs e)
{
if (e.Name == "Me")
PictureBox1.Image = Image.fromFile("");
}
If you add somewhere in your application new picture to collection, it will raise PictureAdded event, which you can handle and update PictureBox. CPU is not wasted in this case.
I'm not really writing an alarm clock application, but it will help to illustrate my question.
Let's say that I have a method in my application, and I want this method to be called every hour on the hour (e.g. at 7:00 PM, 8:00 PM, 9:00 PM etc.). I could create a Timer and set its Interval to 3600000, but eventually this would drift out of sync with the system clock. Or I could use a while() loop with Thread.Sleep(n) to periodically check the system time and call the method when the desired time is reached, but I don't like this either (Thread.Sleep(n) is a big code smell for me).
What I'm looking for is some method in .Net that lets me pass in a future DateTime object and a method delegate or event handler, but I haven't been able to find any such thing. I suspect there's a method in the Win32 API that does this, but I haven't been able to find that, either.
Or, you could create a timer with an interval of 1 second and check the current time every second until the event time is reached, if so, you raise your event.
You can make a simple wrapper for that :
public class AlarmClock
{
public AlarmClock(DateTime alarmTime)
{
this.alarmTime = alarmTime;
timer = new Timer();
timer.Elapsed += timer_Elapsed;
timer.Interval = 1000;
timer.Start();
enabled = true;
}
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
if(enabled && DateTime.Now > alarmTime)
{
enabled = false;
OnAlarm();
timer.Stop();
}
}
protected virtual void OnAlarm()
{
if(alarmEvent != null)
alarmEvent(this, EventArgs.Empty);
}
public event EventHandler Alarm
{
add { alarmEvent += value; }
remove { alarmEvent -= value; }
}
private EventHandler alarmEvent;
private Timer timer;
private DateTime alarmTime;
private bool enabled;
}
Usage:
AlarmClock clock = new AlarmClock(someFutureTime);
clock.Alarm += (sender, e) => MessageBox.Show("Wake up!");
Please note the code above is very sketchy and not thread safe.
Interesting, I've actually come across a very similar issue and went looking for a method in the .Net framework that would handle this scenario. In the end, we ended up implementing our own solution that was a variation on a while loop w/ Thread.Sleep(n) where n gets smaller the closer you get to the desired target time (logarithmically actually, but with some reasonable thresholds so you're not maxing the cpu when you get close to the target time.) Here's a really simple implementation that just sleeps half the time between now and the target time.
class Program
{
static void Main(string[] args)
{
SleepToTarget Temp = new SleepToTarget(DateTime.Now.AddSeconds(30),Done);
Temp.Start();
Console.ReadLine();
}
static void Done()
{
Console.WriteLine("Done");
}
}
class SleepToTarget
{
private DateTime TargetTime;
private Action MyAction;
private const int MinSleepMilliseconds = 250;
public SleepToTarget(DateTime TargetTime,Action MyAction)
{
this.TargetTime = TargetTime;
this.MyAction = MyAction;
}
public void Start()
{
new Thread(new ThreadStart(ProcessTimer)).Start();
}
private void ProcessTimer()
{
DateTime Now = DateTime.Now;
while (Now < TargetTime)
{
int SleepMilliseconds = (int) Math.Round((TargetTime - Now).TotalMilliseconds / 2);
Console.WriteLine(SleepMilliseconds);
Thread.Sleep(SleepMilliseconds > MinSleepMilliseconds ? SleepMilliseconds : MinSleepMilliseconds);
Now = DateTime.Now;
}
MyAction();
}
}
You could simply reset the timer duration each time it fires, like this:
// using System.Timers;
private void myMethod()
{
var timer = new Timer {
AutoReset = false, Interval = getMillisecondsToNextAlarm() };
timer.Elapsed += (src, args) =>
{
// Do timer handling here.
timer.Interval = getMillisecondsToNextAlarm();
timer.Start();
};
timer.Start();
}
private double getMillisecondsToNextAlarm()
{
// This is an example of making the alarm go off at every "o'clock"
var now = DateTime.Now;
var inOneHour = now.AddHours(1.0);
var roundedNextHour = new DateTime(
inOneHour.Year, inOneHour.Month, inOneHour.Day, inOneHour.Hour, 0, 0);
return (roundedNextHour - now).TotalMilliseconds;
}
You could create an Alarm class which has a dedicated thread which goes to sleep until the specified time, but this will use the Thread.Sleep method. Something like:
/// <summary>
/// Alarm Class
/// </summary>
public class Alarm
{
private TimeSpan wakeupTime;
public Alarm(TimeSpan WakeUpTime)
{
this.wakeupTime = WakeUpTime;
System.Threading.Thread t = new System.Threading.Thread(TimerThread) { IsBackground = true, Name = "Alarm" };
t.Start();
}
/// <summary>
/// Alarm Event
/// </summary>
public event EventHandler AlarmEvent = delegate { };
private void TimerThread()
{
DateTime nextWakeUp = DateTime.Today + wakeupTime;
if (nextWakeUp < DateTime.Now) nextWakeUp = nextWakeUp.AddDays(1.0);
while (true)
{
TimeSpan ts = nextWakeUp.Subtract(DateTime.Now);
System.Threading.Thread.Sleep((int)ts.TotalMilliseconds);
try { AlarmEvent(this, EventArgs.Empty); }
catch { }
nextWakeUp = nextWakeUp.AddDays(1.0);
}
}
}
I know it's a bit of an old question, but I came across this when I was looking for an answer to something else. I thought I'd throw my two cents in here, since I recently had this particular issue.
Another thing you can do is schedule the method like so:
/// Schedule the given action for the given time.
public async void ScheduleAction ( Action action , DateTime ExecutionTime )
{
try
{
await Task.Delay ( ( int ) ExecutionTime.Subtract ( DateTime.Now ).TotalMilliseconds );
action ( );
}
catch ( Exception )
{
// Something went wrong
}
}
Bearing in mind it can only wait up to the maximum value of int 32 (somewhere around a month), it should work for your purposes. Usage:
void MethodToRun ( )
{
Console.WriteLine ("Hello, World!");
}
void CallingMethod ( )
{
var NextRunTime = DateTime.Now.AddHours(1);
ScheduleAction ( MethodToRun, NextRunTime );
}
And you should have a console message in an hour.
What about System.Timers.Timer class ? See http://msdn.microsoft.com/en-us/library/system.timers.timer.aspx
I have used this before with great success:
Vb.net:
Imports System.Threading
Public Class AlarmClock
Public startTime As Integer = TimeOfDay.Hour
Public interval As Integer = 1
Public Event SoundAlarm()
Public Sub CheckTime()
While TimeOfDay.Hour < startTime + interval
Application.DoEvents()
End While
RaiseEvent SoundAlarm()
End Sub
Public Sub StartClock()
Dim clockthread As Thread = New Thread(AddressOf CheckTime)
clockthread.Start()
End Sub
End Class
C#:
using System.Threading;
public class AlarmClock
{
public int startTime = TimeOfDay.Hour;
public int interval = 1;
public event SoundAlarmEventHandler SoundAlarm;
public delegate void SoundAlarmEventHandler();
public void CheckTime()
{
while (TimeOfDay.Hour < startTime + interval) {
Application.DoEvents();
}
if (SoundAlarm != null) {
SoundAlarm();
}
}
public void StartClock()
{
Thread clockthread = new Thread(CheckTime);
clockthread.Start();
}
}
I don't know if the c# works, but the vb works just fine.
Usage in VB:
Dim clock As New AlarmClock
clock.interval = 1 'Interval is in hours, could easily convert to anything else
clock.StartClock()
Then, just add an event handler for the SoundAlarm event.