view Implab/PromiseAwaiter`1.cs @ 251:7c7e9ad6fe4a v3

Prerelease version of RunnableComponent Added draft messaging interfaces Added more more helpers to Xml/SerializationHelpers
author cin
date Sun, 11 Feb 2018 00:49:51 +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;
            }
        }
    }
}