Asynchronous Timed Actions

New in V1.3!

One goal of the appspace is that you use the threads in your application as efficiently as possible. One of your worst enemies there is Thread.Sleep() since it blocks the thread and makes it unusable for anything else. It is especially bad if used in a ccr/appspace thread, since the number of ccr threads is intentionally limited to provide optimal performance, so you should never use sleep there. Also, wouldn't it be a nice thing if we could create timers that don't need additional threads but just use the existing ccr threads?

For these two purposes, the appspace provides the class XcoTimedAction, which allows asynchronously invoking a delayed and/or timed action. In the background it uses ccr timer ports.

Replacing Sleep: Invoking a delayed timed action

When is this needed? For example when you want to try something, and if an exception is thrown you want to wait e.g. 5 seconds and then try again.

Here is how a delayed timed action is defined and executed:

var timedAction = space.CreateTimedAction(
   TimeSpan.FromMilliseconds(500), 
   () => {
	//do something ...
	return XcoTimedAction.Continuation.Stop);
   });
			
   timedAction.InvokeDelayed();
The method CreateTimedAction takes a TimeSpan value (the delay after which the action is executed), and an Func<Continuation> (the function that is executed). You can see that the function returns an enum - this specifies that the action should only be executed once (a different return value is needed when we want to define a timer, see below). Calling the InvokeDelayed method asynchronously starts the action, in the above example with a delay of 500ms.

Replacing timers: Invoking a timed action with reschedule

When is this needed? When you have code that should be executed in an interval, e.g. very 5 seconds.

Here is how a timer is defined and executed:

var timedAction = space.CreateTimedAction(
   TimeSpan.FromMilliseconds(500), 
   () => {
	//do something ...
	return XcoTimedAction.Continuation.Reschedule);
   });
			
   timedAction.Invoke();

  //to stop the timer:
  timedAction.Dispose();
You see that the code is very similar to the first example. The TimeSpan now defines the timer interval. The function now returns "Reschedule", which lets the timed action know that the execution should be scheduled again with the given time interval as delay. By using the method Invoke the first invocation of the defined function starts immediately. You can of course also use InvokeDelayed here, if you don't want the timer to start immediately.

Last edited May 26, 2012 at 1:36 PM by thomass, version 2

Comments

No comments yet.