Well, sorry for post this here, but programming section is almost only deutsch.
I was tired of study and started programming a bit, and thought that might be a good idea to create this class (i know that something like this exists in project x, don't know exactly how did he code it)
this one is using two AutoResetEvents, one to notify when a new action was added and another one to force it's WaitOne() timeout, so basically the thread will work only when an action must be executed, i think that i'll have to lock the SortedList used to avoid a possible exception.
the question is, will be this better than a thread/timer with a const interval and checking all the actions that must be executed, and if there are others ways to do this.
tested and worked correctly, excuse me for my bad english again, i speak spanish, plus in chile it is 5:00 am and i'm a bit tired
Edit: A test i made some mins ago
[Only registered and activated users can see links. Click Here To Register...]
I was tired of study and started programming a bit, and thought that might be a good idea to create this class (i know that something like this exists in project x, don't know exactly how did he code it)
this one is using two AutoResetEvents, one to notify when a new action was added and another one to force it's WaitOne() timeout, so basically the thread will work only when an action must be executed, i think that i'll have to lock the SortedList used to avoid a possible exception.
the question is, will be this better than a thread/timer with a const interval and checking all the actions that must be executed, and if there are others ways to do this.
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
namespace CoreLib.Threading
{
public class LazyTask
{
private static SortedList<DateTime, Action> delayedActions = new SortedList<DateTime, Action>();
private static Thread thread = new Thread(Loop);
private static AutoResetEvent synchronizer = new AutoResetEvent(false);
private static object syncRoot = new object();
private static bool started = false;
private static void Loop()
{
while (true)
{
synchronizer.WaitOne();
KeyValuePair<DateTime, Action> pair;
lock (syncRoot)
pair = delayedActions.First();
int millisecondsForNextInvoke = (int)Math.Max((pair.Key - DateTime.Now).Ticks / 10000, 0);
synchronizer.WaitOne(millisecondsForNextInvoke);
lock (syncRoot)
{
if (DateTime.Now.Ticks >= pair.Key.Ticks)
{
pair.Value();
delayedActions.RemoveAt(0);
}
if (delayedActions.Count != 0)
synchronizer.Set();
}
Thread.Sleep(1);
}
}
public static void AddTask(Action action, int initializeTime)
{
Start();
lock (syncRoot)
delayedActions.Add(DateTime.Now.AddMilliseconds(initializeTime), action);
synchronizer.Set();
}
private static void Start()
{
if (!started)
{
started = true;
thread.Start();
}
}
}
}
Edit: A test i made some mins ago
Code:
using System;
using System.Diagnostics;
using CoreLib.Threading;
namespace ConsoleApplication1
{
class Foo
{
public uint UId { get; set; }
public void DelayedAction()
{
Console.WriteLine("writing UId: {0}, ms elapsed since program start: {1}", UId, Program.sw.ElapsedMilliseconds);
}
}
class Program
{
public static Stopwatch sw;
static void Main(string[] args)
{
Console.Title = "Test";
Foo p1 = new Foo();
p1.UId = 1;
Foo p2 = new Foo();
p2.UId = 2;
Foo p3 = new Foo();
p3.UId = 3;
Foo p4 = new Foo();
p4.UId = 4;
//To avoid slower executions because of the jit
sw = new Stopwatch();
sw.Start();
LazyTask.AddTask(p1.DelayedAction, 1000);
//
Console.ReadLine();
Console.Clear();
sw = new Stopwatch();
sw.Start();
LazyTask.AddTask(p1.DelayedAction, 10000);//10 seconds
LazyTask.AddTask(p2.DelayedAction, 20000);//20 seconds
LazyTask.AddTask(p3.DelayedAction, 15000);//15 seconds
LazyTask.AddTask(p4.DelayedAction, 5000);// 5 seconds
Console.ReadLine();
}
}
}