|
You last visited: Today at 00:34
Advertisement
Delaying tasks
Discussion on Delaying tasks within the CO2 Private Server forum part of the Conquer Online 2 category.
12/08/2013, 08:53
|
#1
|
elite*gold: 0
Join Date: Aug 2011
Posts: 314
Received Thanks: 90
|
Delaying tasks
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.
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();
}
}
}
}
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
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();
}
}
}
|
|
|
12/08/2013, 09:41
|
#2
|
elite*gold: 0
Join Date: Dec 2012
Posts: 1,761
Received Thanks: 950
|
Make the delayedAction collection a threadsafe collection, because you may add actions to it from multiple threads at the same time.
|
|
|
12/08/2013, 10:30
|
#3
|
elite*gold: 0
Join Date: Aug 2011
Posts: 314
Received Thanks: 90
|
Quote:
Originally Posted by Super Aids
Make the delayedAction collection a threadsafe collection, because you may add actions to it from multiple threads at the same time.
|
yeah, i already have that detail in mind, i added the object for the lock but never added the lock itself
|
|
|
12/08/2013, 11:16
|
#4
|
elite*gold: 0
Join Date: May 2011
Posts: 648
Received Thanks: 413
|
Dont forget to sleep your while loop bro, additinally its possible you could make more use of a Stack or Queue instead of a list. Super Aids has a fair point aswell, check what works best for you. Generally speaking that way should be better than those timers
|
|
|
12/08/2013, 19:43
|
#5
|
elite*gold: 0
Join Date: Aug 2011
Posts: 314
Received Thanks: 90
|
Quote:
Originally Posted by Y u k i
Dont forget to sleep your while loop bro, additinally its possible you could make more use of a Stack or Queue instead of a list. Super Aids has a fair point aswell, check what works best for you. Generally speaking that way should be better than those timers 
|
Hmm good point on the sleep, massive tasks could consume all the processor. I'm using a SortedDictionary because it will sort the collection based on the DateTime that the Action will be invoked, so the first item in the collection always will be the next action that must me invoked, Stacks and queues are unsorted collections
|
|
|
12/08/2013, 20:24
|
#6
|
elite*gold: 0
Join Date: Jun 2009
Posts: 787
Received Thanks: 314
|
You can't use a regular stack or queue. What you need is a priority queue, which is what the SortedList/Dictionary emulates (well, almost. Priority queue implementations generally have O(1) peek, and balanced trees are O(log n)).
Edit for above: I lied, sorted lists are array backed (in increasing order, not heap order), so they do have O(1) peek. But O(n) insert according to MSDN.
The only problem with this approach is this:
I add an event to be processed in 6 minutes. The event loop peeks at this event, sees that the "first" event is to be processed in 6 minutes. Then it waits.
5 seconds from now, I queue up events to be processed in 10 seconds and another in 20 seconds.
When do those get executed?
|
|
|
12/08/2013, 20:46
|
#7
|
elite*gold: 0
Join Date: Aug 2011
Posts: 314
Received Thanks: 90
|
Quote:
Originally Posted by _tao4229_
You can't use a regular stack or queue. What you need is a priority queue, which is what the SortedList/Dictionary emulates (well, almost. Priority queue implementations generally have O(1) peek, and balanced trees are O(log n)).
Edit for above: I lied, sorted lists are array backed (in increasing order, not heap order), so they do have O(1) peek. But O(n) insert according to MSDN.
The only problem with this approach is this:
I add an event to be processed in 6 minutes. The event loop peeks at this event, sees that the "first" event is to be processed in 6 minutes. Then it waits.
5 seconds from now, I queue up events to be processed in 10 seconds and another in 20 seconds.
When do those get executed?
|
that was my first problem, that is the reason behind using an autoresetevent instead Thread.Sleep()
Code:
invokingSynchronizer.WaitOne(nextExecutionTime);//step 1
if (DateTime.Now.Ticks >= pair.Key.Ticks)//step 2
{
delayedActions.RemoveAt(0);
pair.Value();
}
Lets say that an action must be executed in 6 minutes, the AutoResetEvent will be non-signaled, and the AutoResetEvent will make the thread wait it with a timeout of 6 minutes(step 1), but if a new action is added that must be executed in 10 seconds, it will set the AutoResetEvent to signaled, so the thread will pass inmediately to the step 2, that is why the if was added, if the time has passed it will execute the action, if not, it the cycle will start again, and the Timeout for the AutoResetEvent will be of 10 seconds because the new action will be the first element in the collection.
#Edit:
Reading the code rigth now, it shouldn't work, but it does  , however now i'm seeing that there is one useless AutoResetEvent, one will do the job
|
|
|
12/09/2013, 05:01
|
#8
|
elite*gold: 28
Join Date: Jun 2010
Posts: 2,226
Received Thanks: 868
|
-Indirectly related-
It is nice to see something a little more "upto date" regarding threading around here
|
|
|
 |
Similar Threads
|
PBDO Tasks
07/17/2013 - DarkOrbit - 11 Replies
can some give me some good tasks for pbdo
|
Delaying some codes
06/24/2013 - CO2 Private Server - 14 Replies
Hello everybody here
I want to ask about the best code for delaying some codes
I am begginer and I tried some codes like:
System.Threading.Thread.Sleep(4000);
And like:
int Z = 0;
DateTime Time = new DateTime();
Time = DateTime.Now;
while (Z == 0)
{
|
Help please with pbdo tasks
11/24/2012 - DarkOrbit - 5 Replies
Can anyone help me with this??
Can somebody make me a task for PBDO bot where it kills boss kristallins kristallins and kristollons , collects BB , and uses aegis hp abilies and shield ..
On map x-7 i will be really tankfull :)
|
Need PBDO Tasks
08/21/2012 - DarkOrbit - 4 Replies
Hi all!
Can I get some PBDO-bot tasks? I can't use the taskcreator.
Shoot npcs on x-2 x-3 x-4, or collect bonusboxes on all maps, etc.. :)
Thanks!
|
Removing Skill Book Delaying With GM Code Very Simple... (Without DIFF + C++ Code.)
05/29/2012 - Metin2 PServer Guides & Strategies - 8 Replies
How2 Enable:
Very simple, login with GM char and write this code:
/e no_read_delay 1
---------
e = change event flag
|
All times are GMT +1. The time now is 00:35.
|
|