public async void Start(TimeSpan interval)
        {
            if (interval < TimeSpan.Zero) throw new ArgumentOutOfRangeException("interval");

            lock (_stateLock)
            {
                if (_state == PortableTimerState.Disposed)
                    throw new ObjectDisposedException("PortableTimer");

                if (_state == PortableTimerState.Waiting)
                    throw new InvalidOperationException("The timer already set");

                if (_cancel.IsCancellationRequested) return;

                _state = PortableTimerState.Waiting;
            }

            try
            {
                await Task.Delay(interval, _cancel.Token);
            }
            finally
            {
                lock (_stateLock)
                    _state = PortableTimerState.NotWaiting;
            }

            if (!_cancel.Token.IsCancellationRequested)
            {
                await Task.Run(() => _onTick(_cancel.Token));
            }
        }
Пример #2
0
        public async void Start(TimeSpan interval)
        {
            if (interval < TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException(nameof(interval));
            }

            lock (_stateLock)
            {
                if (_state == PortableTimerState.Disposed)
                {
                    throw new ObjectDisposedException("PortableTimer");
                }

                // There's a little bit of raciness here, but it's needed to support the
                // current API, which allows the tick handler to reenter and set the next interval.

                if (_state == PortableTimerState.Waiting)
                {
                    throw new InvalidOperationException("The timer is already set.");
                }

                if (_cancel.IsCancellationRequested)
                {
                    return;
                }

                _state = PortableTimerState.Waiting;
            }

            try
            {
                if (interval > TimeSpan.Zero)
                {
                    await Task.Delay(interval, _cancel.Token).ConfigureAwait(false);
                }

                _state = PortableTimerState.Active;

                if (!_cancel.Token.IsCancellationRequested)
                {
                    _onTick(_cancel.Token);
                }
            }
            catch (TaskCanceledException tcx)
            {
                SelfLog.WriteLine("The timer was canceled during invocation: {0}", tcx);
            }
            finally
            {
                lock (_stateLock)
                    _state = PortableTimerState.NotWaiting;
            }
        }
Пример #3
0
        public async void Start(TimeSpan interval)
        {
            if (interval < TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException(nameof(interval));
            }

            lock (_stateLock)
            {
                if (_state == PortableTimerState.Disposed)
                {
                    throw new ObjectDisposedException("PortableTimer");
                }

                if (_state == PortableTimerState.Waiting)
                {
                    throw new InvalidOperationException("The timer already set");
                }

                if (_cancel.IsCancellationRequested)
                {
                    return;
                }

                _state = PortableTimerState.Waiting;
            }

            try
            {
                if (!_cancel.Token.IsCancellationRequested)
                {
                    await Task.Delay(interval, _cancel.Token);
                }
            }
            catch (TaskCanceledException) when(_cancel.IsCancellationRequested)
            {
                // currently disposing
            }
            finally
            {
                lock (_stateLock)
                    _state = PortableTimerState.NotWaiting;
            }

            if (!_cancel.Token.IsCancellationRequested)
            {
                await Task.Run(() => _onTick(_cancel.Token));
            }
        }
Пример #4
0
        public void Dispose()
        {
            _cancel.Cancel();

            while (true)
            {
                // Thread.Sleep() would be handy here...

                lock (_stateLock)
                {
                    if (_state == PortableTimerState.Disposed ||
                        _state == PortableTimerState.NotWaiting)
                    {
                        _state = PortableTimerState.Disposed;
                        return;
                    }
                }
            }
        }
Пример #5
0
        public void Dispose()
        {
            _cancel.Cancel();

            while (true)
            {
                // Thread.Sleep() would be handy here...

                lock (_stateLock)
                {
                    if (_state == PortableTimerState.Disposed ||
                        _state == PortableTimerState.NotWaiting)
                    {
                        _state = PortableTimerState.Disposed;
                        return;
                    }
                }
            }
        }
Пример #6
0
        public void Dispose()
        {
            _cancel.Cancel();

            while (true)
            {
                lock (_stateLock)
                {
                    if (_state == PortableTimerState.Disposed ||
                        _state == PortableTimerState.NotWaiting)
                    {
                        _state = PortableTimerState.Disposed;
                        return;
                    }
                }

                Thread.Sleep(10);
            }
        }
        public async void Start(TimeSpan interval)
        {
            if (interval < TimeSpan.Zero) throw new ArgumentOutOfRangeException(nameof(interval));

            lock (_stateLock)
            {
                if (_state == PortableTimerState.Disposed)
                    throw new ObjectDisposedException("PortableTimer");

                // There's a little bit of raciness here, but it's needed to support the
                // current API, which allows the tick handler to reenter and set the next interval.

                if (_state == PortableTimerState.Waiting)
                    throw new InvalidOperationException("The timer is already set.");

                if (_cancel.IsCancellationRequested) return;

                _state = PortableTimerState.Waiting;
            }

            try
            {
                if (interval > TimeSpan.Zero)
                    await Task.Delay(interval, _cancel.Token).ConfigureAwait(false);

                _state = PortableTimerState.Active;

                if (!_cancel.Token.IsCancellationRequested)
                {
                    _onTick(_cancel.Token);
                }
            }
            catch (TaskCanceledException tcx)
            {
                SelfLog.WriteLine("The timer was canceled during invocation: {0}", tcx);
            }
            finally
            {
                lock (_stateLock)
                    _state = PortableTimerState.NotWaiting;
            }
        }
        public void Dispose()
        {
            _cancel.Cancel();

            while (true)
            {
                lock (_stateLock)
                {
                    if (_state == PortableTimerState.Disposed ||
                        _state == PortableTimerState.NotWaiting)
                    {
                        _state = PortableTimerState.Disposed;
                        return;
                    }
                }

// On the very old platforms, we've got no option but to spin here.
#if THREAD
                Thread.Sleep(10);
#endif
            }
        }
        public void Dispose()
        {
            _cancel.Cancel();

            while (true)
            {
                lock (_stateLock)
                {
                    if (_state == PortableTimerState.Disposed ||
                        _state == PortableTimerState.NotWaiting)
                    {
                        _state = PortableTimerState.Disposed;
                        return;
                    }
                }

// On the very old platforms, we've got no option but to spin here.
#if THREAD
                Thread.Sleep(10);
#endif
            }
        }
        public void Dispose()
        {
            _cancel.Cancel();

            while (true)
            {
                lock (_stateLock)
                {
                    if (_state == PortableTimerState.Disposed ||
                        _state == PortableTimerState.NotWaiting)
                    {
                        _state = PortableTimerState.Disposed;
                        return;
                    }
                }

                Thread.Sleep(10);
            }
        }