public ThreadTimer(Fun0 <Unit> cb, int ms) { entry = Primitive.GetEventloopEntry(); if (ms <= 0) { timer = null; entry.Post(() => { cb.Apply(); }); } else { timer = new Timer((object state0) => { if (entry != null) { entry.Post(() => { cb.Apply(); }); } }, null, ms, Timeout.Infinite); } }
public static A Finally <A>(Fun0 <A> action, Fun0 <Unit> handler) { try { return((A)action.Apply()); } finally { handler.Apply(); } }
public static A Catch <A>(Fun0 <A> action, Fun1 <Exception, A> handler) { try { return((A)action.Apply()); } catch (Exception exn) { return((A)handler.Apply(exn)); } }
// For now, the MainConsole enters an event loop that handles // ReadLine from the Console. Later other asynchronous api's can // be added through the AsyncGlobal class, keeping the application // active as long as there are 'on' handlers installed. public static A MainConsole <A>(Fun0 <A> f) { A x = (A)f.Apply(); while (!AsyncGlobal.AllDone()) { if (onReadLine != null) { string s = Console.In.ReadLine(); Async <string> res = onReadLine; onReadLine = null; res.Supply(s); // this may set onReadLine again } else { // bad Primitive.Trace("MainConsole: active async's but no readline"); break; } } return(x); }
// For now, the MainConsole enters an event loop that handles // ReadLine from the Console. Later other asynchronous api's can // be added through the AsyncGlobal class, keeping the application // active as long as there are 'on' handlers installed. public static A MainConsole <A>(Fun0 <A> f) { A x = (A)f.Apply(); while (activeEntries > 0 || work.Count > 0) { Action action; lock (workMutex) { action = (work.Count > 0 ? work.Dequeue() : null); } if (action != null) { action(); } else { // wait for new work items // todo: we could implement efficient timers here by using timeouts workEvent.WaitOne(); } } return(x); }
public static A Call <A>(this Fun0 <A> f) { return((A)f.Apply()); }