Zzz – Rev 1

Subversion Repositories:
Rev:
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Zzz.Utilities
{
    public class PauseTokenSource : IDisposable
    {
        #region Static Fields and Constants

        internal static Task SCompletedTask = Task.FromResult(true);

        #endregion

        #region Public Enums, Properties and Fields

        public bool IsPaused
        {
            get => _mPaused != null;
            set
            {
                if (value)
                {
                    Interlocked.CompareExchange(
                        ref _mPaused, new TaskCompletionSource<bool>(), null);
                }
                else
                {
                    while (true)
                    {
                        var tcs = _mPaused;
                        if (tcs == null)
                        {
                            return;
                        }

                        if (Interlocked.CompareExchange(ref _mPaused, null, tcs) == tcs)
                        {
                            tcs.SetResult(true);
                            break;
                        }
                    }
                }
            }
        }

        public PauseToken Token => new PauseToken(this);

        #endregion

        #region Private Delegates, Events, Enums, Properties, Indexers and Fields

        private TaskCompletionSource<bool> _mPaused;

        #endregion

        #region Constructors, Destructors and Finalizers

        public void Dispose()
        {
            SCompletedTask?.Dispose();
            SCompletedTask = null;
        }

        #endregion

        #region Private Methods

        internal Task WaitWhilePausedAsync()
        {
            var cur = _mPaused;
            return cur != null ? cur.Task : SCompletedTask;
        }

        #endregion

        #region Nested Types

        public readonly struct PauseToken
        {
            private readonly PauseTokenSource _mSource;

            internal PauseToken(PauseTokenSource source)
            {
                _mSource = source;
            }

            public bool IsPaused => _mSource != null && _mSource.IsPaused;

            public Task WaitWhilePausedAsync()
            {
                return IsPaused ? _mSource.WaitWhilePausedAsync() : SCompletedTask;
            }
        }

        #endregion
    }
}

Generated by GNU Enscript 1.6.5.90.