private void IssueRequest(IPathRequest request, SteerForPathComponent steerer)
        {
            var action = new OneTimeAction((ignored) =>
            {
                steerer.RequestPath(request);
            });

            NavLoadBalancer.defaultBalancer.Add(action, this.retryDelay, true);
        }
Exemplo n.º 2
0
        private void Update()
        {
            if (Input.GetKeyUp(KeyCode.Alpha1))
            {
                //You can pass it a matching named method
                var action = new OneTimeAction(DoWork);

                //Here we schedule the action to take place as soon as possible. Since this is a one time action, the interval is irrelevant.
                ExamplesLoadBalancer.examplesBalancer.Add(action);
            }
            else if (Input.GetKeyUp(KeyCode.Alpha2))
            {
                //You can also pass it an anonymous method.
                var action = new OneTimeAction(
                    (t) => Debug.Log("Work done after " + t.ToString() + " seconds"));

                //Here we schedule the action to take place after a short delay or as soon after that delay as possible.
                //Since this is a one time action, the interval is irrelevant but in this case used as the delay.
                ExamplesLoadBalancer.examplesBalancer.Add(action, 2f, true);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// The method to send a start message and wait for the end message.
        /// </summary>
        /// <param name="startMessage">The start message.</param>
        /// <param name="onMessage">The action to send the message.</param>
        /// <param name="continueAction">The action to execute once a <see cref="MessageGateResult{TEnd}"/> was created.</param>
        /// <param name="timeout">
        /// Optionally a timeout after which the method will return, without sending the result.
        /// By default the timeout is <see cref="NoTimout"/>
        /// </param>
        /// <param name="cancellationToken">
        /// Optionally a cancellation token to cancel the continue operation. By default no CancellationToken will be used.
        /// </param>
        /// <remarks>
        /// <para>For an example how to use this class see the type documentation.</para>
        /// </remarks>
        public void SendAndContinue(TStart startMessage, Action <Message> onMessage, Action <MessageGateResult <TEnd> > continueAction, int timeout = NoTimout,
                                    CancellationToken cancellationToken = default)
        {
            if (startMessage == null)
            {
                throw new ArgumentNullException(nameof(startMessage));
            }

            if (onMessage == null)
            {
                throw new ArgumentNullException(nameof(onMessage));
            }

            if (continueAction == null)
            {
                throw new ArgumentNullException(nameof(continueAction));
            }

            CancellationToken userCancelToken      = cancellationToken;
            CancellationToken timeoutCancelToken   = default;
            List <CancellationTokenSource> sources = new List <CancellationTokenSource>();

            if (timeout != NoTimout)
            {
                CancellationTokenSource timeoutSource = new CancellationTokenSource(timeout);
                sources.Add(timeoutSource);
                timeoutCancelToken = timeoutSource.Token;
            }
            CancellationTokenSource combinedSource = CancellationTokenSource.CreateLinkedTokenSource(userCancelToken, timeoutCancelToken);

            cancellationToken = combinedSource.Token;
            sources.Add(combinedSource);

            MessageDomain.CreateNewDomainsFor(startMessage);
            CancellationTokenRegistration register = default;
            OneTimeAction action = new OneTimeAction(OnReceived);

            continueActions.TryAdd(startMessage.MessageDomain, action);
            register = cancellationToken.Register(OnCancel);

            onMessage(startMessage);

            void Dispose()
            {
                foreach (CancellationTokenSource tokenSource in sources)
                {
                    tokenSource.Dispose();
                }

                register.Dispose();
            }

            void OnReceived(Message message)
            {
                if (!continueActions.TryRemove(startMessage.MessageDomain, out _))
                {
                    return;
                }

                MessageDomain.TerminateDomainsOf(startMessage);
                if (message.TryGet(out TEnd endMessage))
                {
                    continueAction(new MessageGateResult <TEnd>(MessageGateResultKind.Success, endMessage,
                                                                Enumerable.Empty <ExceptionMessage>()));
                }
                else
                {
                    ExceptionMessage exceptionMessage = message.Get <ExceptionMessage>();
                    continueAction(
                        new MessageGateResult <TEnd>(MessageGateResultKind.Exception, null, new[] { exceptionMessage }));
                }

                Dispose();
            }

            void OnCancel()
            {
                if (!continueActions.TryRemove(startMessage.MessageDomain, out _))
                {
                    return;
                }

                MessageDomain.TerminateDomainsOf(startMessage);
                MessageGateResultKind resultKind = MessageGateResultKind.Success;

                if (userCancelToken.IsCancellationRequested)
                {
                    resultKind = MessageGateResultKind.Canceled;
                }
                else if (timeoutCancelToken.IsCancellationRequested)
                {
                    resultKind = MessageGateResultKind.Timeout;
                }

                MessageGateResult <TEnd> result =
                    new MessageGateResult <TEnd>(resultKind, null, Enumerable.Empty <ExceptionMessage>());

                continueAction(result);
                Dispose();
            }
        }
 public SynchronizationContextService()
 {
     _setUiSchedulers = new OneTimeAction(DoSetApplicationUiScheduler);
 }