TerminalScheduler.cs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. using System;
  2. using System.Reactive.Concurrency;
  3. using System.Reactive.Disposables;
  4. using Terminal.Gui;
  5. namespace ReactiveExample;
  6. public class TerminalScheduler : LocalScheduler
  7. {
  8. public static readonly TerminalScheduler Default = new ();
  9. private TerminalScheduler () { }
  10. public override IDisposable Schedule<TState> (
  11. TState state,
  12. TimeSpan dueTime,
  13. Func<IScheduler, TState, IDisposable> action
  14. )
  15. {
  16. IDisposable PostOnMainLoop ()
  17. {
  18. var composite = new CompositeDisposable (2);
  19. var cancellation = new CancellationDisposable ();
  20. Application.Invoke (
  21. () =>
  22. {
  23. if (!cancellation.Token.IsCancellationRequested)
  24. {
  25. composite.Add (action (this, state));
  26. }
  27. }
  28. );
  29. composite.Add (cancellation);
  30. return composite;
  31. }
  32. IDisposable PostOnMainLoopAsTimeout ()
  33. {
  34. var composite = new CompositeDisposable (2);
  35. object timeout = Application.AddTimeout (
  36. dueTime,
  37. () =>
  38. {
  39. composite.Add (action (this, state));
  40. return false;
  41. }
  42. );
  43. composite.Add (Disposable.Create (() => Application.RemoveTimeout (timeout)));
  44. return composite;
  45. }
  46. return dueTime == TimeSpan.Zero
  47. ? PostOnMainLoop ()
  48. : PostOnMainLoopAsTimeout ();
  49. }
  50. }