view Implab/PromiseAwaiter.cs @ 281:e0916ddc9950 v3 tip

code cleanup and refactoring
author cin
date Fri, 01 Jun 2018 21:35:24 +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 : INotifyCompletion {
        class PromiseEvent : IResolvable {
            IDispatcher m_dispatcher;
            
            Action m_handler;
            
            public PromiseEvent(Action handler, IDispatcher dispatcher) {
                m_handler = handler;
                m_dispatcher = dispatcher;
            }

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

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

        readonly IPromise m_promise;
        readonly IDispatcher m_dispatcher;

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

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

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

        public void GetResult() {
            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;
            }
        }
    }
}