Пример #1
0
        /// <summary>
        /// Creates a new instance of the <see cref="DisposableAsyncLazy{T}"/> type
        /// with the specified factory and disposal operations.
        /// </summary>
        /// <param name="factory">The factory that is used to instantiate the value.</param>
        /// <param name="disposal">The disposal the is used to destroy the value.</param>
        /// <param name="options">
        /// A combination of <see cref="DisposableAsyncLazyOptions"/> flags that control the
        /// behavior of the created <see cref="DisposableAsyncLazy{T}"/>
        /// or <see cref="DisposableAsyncLazyOptions.None"/>.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Thrown if either <paramref name="factory"/> or <paramref name="disposal"/> is <c>null</c>.
        /// </exception>
        public DisposableAsyncLazy(
            Func <CancellationToken, Task <T> > factory,
            Func <T, Task> disposal,
            DisposableAsyncLazyOptions options = default)
        {
            if (factory == null)
            {
                throw new ArgumentNullException(nameof(factory));
            }

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

            _cancellationSource = new CancellationTokenSource();

            async Task <T> WithCancellation()
            {
                try
                {
                    return(await factory(_cancellationSource.Token).ConfigureAwait(false));
                }
                catch (OperationCanceledException) when(_cancellationSource.IsCancellationRequested)
                {
                    throw new ObjectDisposedException(GetType().FullName);
                }
            }

            _disposal = disposal;
            _factory  = WithCancellation;

            if ((options & DisposableAsyncLazyOptions.RetryOnFailure) == DisposableAsyncLazyOptions.RetryOnFailure)
            {
                _factory = RetryOnFailure(_factory);
            }

            if ((options & DisposableAsyncLazyOptions.ExecuteOnCallingThread)
                != DisposableAsyncLazyOptions.ExecuteOnCallingThread)
            {
                _factory = RunOnThreadPool(_factory);
            }

            _instance = new Lazy <Task <T> >(_factory);

            if ((options & DisposableAsyncLazyOptions.Autostart) == DisposableAsyncLazyOptions.Autostart)
            {
                Start();
            }
        }
Пример #2
0
        /// <summary>
        /// Creates a new instance of the <see cref="DisposableAsyncLazy{T}"/> type
        /// with the specified factory and disposal operations.
        /// </summary>
        /// <param name="factory">The factory that is used to instantiate the value.</param>
        /// <param name="disposal">The disposal the is used to destroy the value.</param>
        /// <param name="options">
        /// A combination of <see cref="DisposableAsyncLazyOptions"/> flags that control the
        /// behavior of the created <see cref="DisposableAsyncLazy{T}"/>
        /// or <see cref="DisposableAsyncLazyOptions.None"/>.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Thrown if either <paramref name="factory"/> or <paramref name="disposal"/> is <c>null</c>.
        /// </exception>
        public DisposableAsyncLazy(
            Func <Task <T> > factory, Func <T, Task> disposal, DisposableAsyncLazyOptions options = default)
        {
            if (factory == null)
            {
                throw new ArgumentNullException(nameof(factory));
            }

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

            // TODO: Validate the options.

            _cancellationSource = new CancellationTokenSource();
            _disposal           = disposal;
            _factory            = factory;

            if ((options & DisposableAsyncLazyOptions.RetryOnFailure) == DisposableAsyncLazyOptions.RetryOnFailure)
            {
                _factory = RetryOnFailure(_factory);
            }

            if ((options & DisposableAsyncLazyOptions.ExecuteOnCallingThread)
                != DisposableAsyncLazyOptions.ExecuteOnCallingThread)
            {
                _factory = RunOnThreadPool(_factory);
            }

            _instance = new Lazy <Task <T> >(_factory);

            if ((options & DisposableAsyncLazyOptions.Autostart) != DisposableAsyncLazyOptions.Autostart)
            {
                Start();
            }
        }
Пример #3
0
 /// <summary>
 /// Creates a new instance of the <see cref="DisposableAsyncLazy{T}"/> type
 /// with the specified factory and disposal operations.
 /// </summary>
 /// <param name="factory">The factory that is used to instantiate the value.</param>
 /// <param name="options">
 /// A combination of <see cref="DisposableAsyncLazyOptions"/> flags that control the
 /// behavior of the created <see cref="DisposableAsyncLazy{T}"/>
 /// or <see cref="DisposableAsyncLazyOptions.None"/>.
 /// </param>
 /// <exception cref="ArgumentNullException">Thrown if <paramref name="factory"/>  is <c>null</c>.</exception>
 public DisposableAsyncLazy(
     Func <CancellationToken, Task <T> > factory,
     DisposableAsyncLazyOptions options = default)
     : this(factory, _noDisposal, options)
 {
 }