Chapter5/5.1_DotnetInteraction/StandardModuleSampleAsync/AsyncPSCmdlet.cs
using System;
using System.Management.Automation; using System.Threading; using System.Threading.Tasks; namespace StandardModuleSampleAsync { /// <summary> /// Base class for Async PSCmdlet /// </summary> public abstract class AsyncPSCmdlet : PSCmdlet, IDisposable { /// <summary> /// The source for cancellation tokens that can be used to cancel the operation. /// </summary> readonly CancellationTokenSource cancellationSource = new CancellationTokenSource(); /// <summary> /// Initialise the <see cref="AsyncPSCmdlet"/>. /// </summary> protected AsyncPSCmdlet() { } /// <summary> /// Finaliser for <see cref="AsyncPSCmdlet"/>. /// </summary> ~AsyncPSCmdlet() { Dispose(false); } /// <summary> /// Dispose of resources being used by the Cmdlet. /// </summary> public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// <summary> /// Dispose of resources being used by the Cmdlet. /// </summary> protected virtual void Dispose(bool disposing) { if (disposing) { cancellationSource.Dispose(); } } /// <summary> /// Asynchronously perform Cmdlet pre-processing. /// </summary> protected virtual Task BeginProcessingAsync() { return BeginProcessingAsync(cancellationSource.Token); } /// <summary> /// Asynchronously perform Cmdlet pre-processing. /// </summary> protected virtual Task BeginProcessingAsync(CancellationToken cancellationToken) { return Task.CompletedTask; } /// <summary> /// Asynchronously perform Cmdlet processing. /// </summary> protected virtual Task ProcessRecordAsync() { return ProcessRecordAsync(cancellationSource.Token); } /// <summary> /// Asynchronously perform Cmdlet processing. /// </summary> protected virtual Task ProcessRecordAsync(CancellationToken cancellationToken) { return Task.CompletedTask; } /// <summary> /// Asynchronously perform Cmdlet post-processing. /// </summary> protected virtual Task EndProcessingAsync() { return EndProcessingAsync(cancellationSource.Token); } /// <summary> /// Asynchronously perform Cmdlet post-processing. /// </summary> protected virtual Task EndProcessingAsync(CancellationToken cancellationToken) { return Task.CompletedTask; } protected sealed override void BeginProcessing() { PowerShellSynchronizationContext.RunSynchronized(() => BeginProcessingAsync()); } protected sealed override void ProcessRecord() { PowerShellSynchronizationContext.RunSynchronized(() => ProcessRecordAsync()); } protected sealed override void EndProcessing() { PowerShellSynchronizationContext.RunSynchronized(() => EndProcessingAsync()); } /// <summary> /// Interrupt Cmdlet processing (if possible). /// </summary> protected sealed override void StopProcessing() { cancellationSource.Cancel(); base.StopProcessing(); } /// <summary> /// Write a progress record to the output stream. /// </summary> protected void WriteVerboseProgress(ProgressRecord progressRecord) { if (progressRecord == null) throw new ArgumentNullException(nameof(progressRecord)); WriteProgress(progressRecord); WriteVerbose(progressRecord.StatusDescription); } /// <summary> /// Write a progress record to the output stream. /// </summary> protected void WriteVerboseProgress(ProgressRecord progressRecord, string messageOrFormat, params object[] formatArguments) { if (progressRecord == null) throw new ArgumentNullException(nameof(progressRecord)); if (String.IsNullOrWhiteSpace(messageOrFormat)) throw new ArgumentException("Argument cannot be null, empty, or composed entirely of whitespace: 'messageOrFormat'.", nameof(messageOrFormat)); if (formatArguments == null) throw new ArgumentNullException(nameof(formatArguments)); progressRecord.StatusDescription = String.Format(messageOrFormat, formatArguments); WriteVerboseProgress(progressRecord); } /// <summary> /// Write a completed progress record to the output stream. /// </summary> protected void WriteProgressCompletion(ProgressRecord progressRecord, string completionMessageOrFormat, params object[] formatArguments) { if (progressRecord == null) throw new ArgumentNullException(nameof(progressRecord)); if (String.IsNullOrWhiteSpace(completionMessageOrFormat)) throw new ArgumentException("Argument cannot be null, empty, or composed entirely of whitespace: 'completionMessageOrFormat'.", nameof(completionMessageOrFormat)); if (formatArguments == null) throw new ArgumentNullException(nameof(formatArguments)); progressRecord.StatusDescription = String.Format(completionMessageOrFormat, formatArguments); progressRecord.PercentComplete = 100; progressRecord.RecordType = ProgressRecordType.Completed; WriteProgress(progressRecord); WriteVerbose(progressRecord.StatusDescription); } } } |