248
+ − 1 using System;
+ − 2 using System.Runtime.CompilerServices;
+ − 3 using System.Threading;
+ − 4 using Implab.Parallels;
+ − 5
+ − 6 namespace Implab {
+ − 7 public struct PromiseAwaiter<T> : INotifyCompletion {
+ − 8 class PromiseEvent : IResolvable<T> {
+ − 9 IDispatcher m_dispatcher;
+ − 10
+ − 11 Action m_handler;
+ − 12
+ − 13 public PromiseEvent(Action handler, IDispatcher dispatcher) {
+ − 14 m_handler = handler;
+ − 15 m_dispatcher = dispatcher;
+ − 16 }
+ − 17
+ − 18 public void Resolve(T result) {
+ − 19 m_dispatcher.Enqueue(m_handler);
+ − 20 }
+ − 21
+ − 22 public void Reject(Exception error) {
+ − 23 m_dispatcher.Enqueue(m_handler);
+ − 24 }
+ − 25 }
+ − 26
+ − 27 readonly IPromise<T> m_promise;
+ − 28
+ − 29 readonly IDispatcher m_dispatcher;
+ − 30
+ − 31 public PromiseAwaiter(IPromise<T> promise) {
+ − 32 m_promise = promise;
+ − 33 m_dispatcher = GetDispatcher();
+ − 34 }
+ − 35
+ − 36 public PromiseAwaiter(IPromise<T> promise, IDispatcher dispatcher) {
+ − 37 m_promise = promise;
+ − 38 m_dispatcher = dispatcher;
+ − 39 }
+ − 40
+ − 41 public void OnCompleted(Action continuation) {
+ − 42 if (m_promise != null)
+ − 43 m_promise.Then(new PromiseEvent(continuation, GetDispatcher()));
+ − 44 }
+ − 45
+ − 46 public T GetResult() {
+ − 47 return m_promise.Join();
+ − 48 }
+ − 49
+ − 50 static IDispatcher GetDispatcher() {
+ − 51 if (SynchronizationContext.Current == null)
+ − 52 return ThreadPoolDispatcher.Instance;
+ − 53 return new SyncContextDispatcher(SynchronizationContext.Current);
+ − 54 }
+ − 55
+ − 56 public bool IsCompleted {
+ − 57 get {
+ − 58 return m_promise.IsResolved;
+ − 59 }
+ − 60 }
+ − 61 }
+ − 62 }