Beispiel #1
0
        /// <summary>
        /// AfterFunc waits for the duration to elapse and then calls f in its own goroutine.
        /// It returns a <see cref="Timer"/> that can be used to cancel the call using its Stop method.
        /// </summary>
        public static Timer AfterFunc(TimeSpan duration, Action f)
        {
            if (duration < TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException("duration", duration, "duration must be >= 0");
            }
            if (f == null)
            {
                throw new ArgumentNullException("f");
            }

            var timer = new Timer(duration);

            GoFunc.Run(() =>
            {
                bool ok;
                timer.C.ReceiveOk(out ok);

                if (ok)
                {
                    f();
                }
            }, string.Format("Time.AfterFunc started:{0} duration:{1}", DateTime.Now, duration));

            return(timer);
        }
Beispiel #2
0
        /// <summary>
        /// Creates a new <see cref="Timer"/> that will send the current time on its channel <see cref="C"/> after at least
        /// <paramref name="duration" />.
        /// </summary>
        public Timer(TimeSpan duration)
        {
            _isTimerActive = 1;

            GoFunc.Run(() =>
            {
                bool ok;
                Time.After(duration).ReceiveOk(out ok);
                if (ok)
                {
                    if (Interlocked.CompareExchange(ref _isTimerActive, 0, 1) == 1)
                    {
                        _timerChan.Send(DateTime.Now);
                        _timerChan.Close();
                    }
                }
            }, string.Format("timer started:{0} duration:{1}", DateTime.Now, duration));
        }
Beispiel #3
0
        /// <summary>
        /// DialTimeout acts like Dial but takes a timeout. The timeout includes name resolution, if required.
        /// </summary>
        public static IConn DialTimeout(string network, string address, TimeSpan timeout)
        {
            if (network != "tcp")
            {
                throw new ArgumentException("only 'tcp' network is supported", "network");
            }

            var dialChan    = new Chan <IConn>();
            var timeoutChan = Time.After(timeout);

            GoFunc.Run(() =>
            {
                try
                {
                    var tmpConn = Dial(network, address);
                    dialChan.Send(tmpConn);
                }
                catch
                {
                    // handling timeout below, don't bring down the whole app with an unhandled thread exception
                }
            }, "Net:DialTimeout");

            IConn conn = null;

            Select
            .CaseReceive(dialChan, c => conn = c)
            .CaseReceive(timeoutChan, o =>
            {
                throw new TimeoutException(string.Format("timeout {0} exceed when dialing {1}", timeout, address));
            })
            .NoDefault();

            timeoutChan.Close();

            return(conn);
        }