예제 #1
0
        public void Dispose()
        {
            if (_isDisposed)
            {
                return;
            }

            Factotum.DisposeAndNull(ref _reader);
            _isDisposed = true;
        }
        /// <summary>
        ///     Executes a wrapper for the command's logic.
        /// </summary>
        /// <param name="parameter">
        ///     The parameter to pass to the command's logic.
        /// </param>
        /// <param name="executeAsynchronously">
        ///     A <see cref="bool"/> value that indicates whether the command's logic should be
        ///     executed asynchronously.
        /// </param>
        protected void ExecuteInternal(object parameter, bool executeAsynchronously)
        {
            lock (_syncLock)
            {
                _dispatcher.VerifyAccess();

                if (IsExecuting)
                {
                    return;
                }
            }

            if (executeAsynchronously)
            {
                lock (_syncLock)
                {
                    Factotum.DisposeAndNull(ref _cancellationTokenSource);
                    _cancellationTokenSource = new CancellationTokenSource();

                    var cancellationToken = _cancellationTokenSource.Token;
                    var task = new Task(() => _execute(parameter, cancellationToken), cancellationToken);

                    task.ContinueWith(
                        t =>
                        _dispatcher.Invoke(
                            new Action(() => CleanUpAfterExecution(t.Exception)),
                            DispatcherPriority.Send),
                        CancellationToken.None);

                    IsExecuting = true;
                    task.Start();
                }
            }
            else
            {
                Exception exception = null;

                IsExecuting = true;
                try
                {
                    _execute(parameter, CancellationToken.None);
                }
                catch (Exception ex)
                    when(!ex.IsFatal())
                    {
                        exception = ex;
                    }
                finally
                {
                    CleanUpAfterExecution(exception);
                }
            }
        }
        private void CleanUpAfterExecution([CanBeNull] Exception exception)
        {
            _dispatcher.VerifyAccess();

            try
            {
                if (exception != null && !exception.IsFatal())
                {
                    _handleException(exception);
                }
            }
            finally
            {
                lock (_syncLock)
                {
                    IsExecuting = false;
                    Factotum.DisposeAndNull(ref _cancellationTokenSource);
                }
            }
        }