public static Int64 schedule(ClosureValue callback, DateTimeOffset executeAt, PeriodValue repeatEvery, String jobName) { long delayInMillis = (executeAt.Ticks - DateTime.Now.Ticks) / 10000; // 1 tick = 100 nanosecond if (delayInMillis < 0) { delayInMillis = 0; } long periodInMillis = repeatEvery == null ? -1L : repeatEvery.TotalMilliseconds(); Int64 jobId = Interlocked.Increment(ref JOB_COUNTER); TimerCallback timer = state => HandleCallback(callback, repeatEvery == null ? jobId : (Int64?)null); JOB_TIMERS[jobId] = new Timer(timer, null, delayInMillis, periodInMillis); return(jobId); }
public static void HandleCallback(ClosureValue callback, Int64?jobIdToCancel) { try { callback.interpret(ApplicationContext.Get()); } finally { // gracefully dispose 1-time job timers (repeated jobs must call cancel) if (jobIdToCancel != null) { Timer timer; JOB_TIMERS.TryRemove((Int64)jobIdToCancel, out timer); } } }
private IMethodDeclaration getClosureDeclaration(Context context, ClosureValue closure) { IMethodDeclaration decl = closure.Method; if (decl.getMemberOf() != null) { // the closure references a member method (useful when a method reference is needed) // in which case we may simply want to return that method to avoid spilling context into method body // this is only true if the closure comes straight from the method's instance context // if the closure comes from an accessible context that is not the instance context // then it is a local variable that needs the closure context to be interpreted Context declaring = context.contextForValue(selector.getName()); if (declaring == closure.getContext()) { return(decl); } } return(new ClosureDeclaration(closure)); throw new NotImplementedException(); }
public ClosureDeclaration(ClosureValue method) : base(method.getName(), method.getParameters(), method.getReturnType()) { this.method = method; }