view Implab/PromiseAwaiter`1.cs @ 260:547a2fc0d93e v3 v3.0.6

minor fixes
author cin
date Fri, 13 Apr 2018 19:14:59 +0300
parents 5cb4826c2c2a
children
line wrap: on
line source

using System;
using System.Runtime.CompilerServices;
using System.Threading;
using Implab.Parallels;

namespace Implab {
    public struct PromiseAwaiter<T> : INotifyCompletion {
        class PromiseEvent : IResolvable<T> {
            IDispatcher m_dispatcher;

            Action m_handler;

            public PromiseEvent(Action handler, IDispatcher dispatcher) {
                m_handler = handler;
                m_dispatcher = dispatcher;
            }

            public void Resolve(T result) {
                m_dispatcher.Enqueue(m_handler);
            }

            public void Reject(Exception error) {
                m_dispatcher.Enqueue(m_handler);
            }
        }

        readonly IPromise<T> m_promise;

        readonly IDispatcher m_dispatcher;

        public PromiseAwaiter(IPromise<T> promise) {
            m_promise = promise;
            m_dispatcher = GetDispatcher();
        }

        public PromiseAwaiter(IPromise<T> promise, IDispatcher dispatcher) {
            m_promise = promise;
            m_dispatcher = dispatcher;
        }

        public void OnCompleted(Action continuation) {
            if (m_promise != null)
                m_promise.Then(new PromiseEvent(continuation, GetDispatcher()));
        }

        public T GetResult() {
            return m_promise.Join();
        }

        static IDispatcher GetDispatcher() {
            if (SynchronizationContext.Current == null)
                return ThreadPoolDispatcher.Instance;
            return new SyncContextDispatcher(SynchronizationContext.Current);
        }

        public bool IsCompleted {
            get {
                return m_promise.IsResolved;
            }
        }
    }
}