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); } } }