/// <summary>
        ///		Run an asynchronous operation using the current thread as its synchronisation context.
        /// </summary>
        /// <param name="asyncOperation">
        ///		A <see cref="Func{TResult}"/> delegate representing the asynchronous operation to run.
        /// </param>
        public static void RunSynchronized(Func <Task> asyncOperation)
        {
            if (asyncOperation == null)
            {
                throw new ArgumentNullException(nameof(asyncOperation));
            }

            var savedContext = Current;

            try {
                using (var synchronizationContext = new ThreadAffinitiveSynchronizationContext()) {
                    SetSynchronizationContext(synchronizationContext);


                    var rootOperationTask = asyncOperation();
                    if (rootOperationTask == null)
                    {
                        throw new InvalidOperationException("The asynchronous operation delegate cannot return null.");
                    }

                    rootOperationTask.ContinueWith(
                        operationTask =>
                        synchronizationContext.TerminateMessagePump(),
                        scheduler:
                        TaskScheduler.Default
                        );


                    synchronizationContext.RunMessagePump();


                    try {
                        rootOperationTask
                        .GetAwaiter()
                        .GetResult();
                    }
                    catch (AggregateException eWaitForTask) // The TPL will almost always wrap an AggregateException around any exception thrown by the async operation.
                    {
                        // Is this just a wrapped exception?
                        var flattenedAggregate = eWaitForTask.Flatten();
                        if (flattenedAggregate.InnerExceptions.Count != 1)
                        {
                            throw; // Nope, genuine aggregate.
                        }


                        // Yep, so rethrow (preserving original stack-trace).
                        ExceptionDispatchInfo
                        .Capture(
                            flattenedAggregate
                            .InnerExceptions[0]
                            )
                        .Throw();
                    }
                }
            }
            finally {
                SetSynchronizationContext(savedContext);
            }
        }
Exemple #2
0
 /// <summary>
 ///		Perform Cmdlet post-processing.
 /// </summary>
 protected sealed override void EndProcessing()
 {
     ThreadAffinitiveSynchronizationContext.RunSynchronized(
         () => EndProcessingAsync()
         );
     PowerShellSink.Instance.UnRegister(GetHashCode());
 }
Exemple #3
0
        /// <summary>
        ///		Perform Cmdlet pre-processing.
        /// </summary>
        protected sealed override void BeginProcessing()
        {
            PowerShellSink.Instance.Register(this);

            ThreadAffinitiveSynchronizationContext.RunSynchronized(
                () => BeginProcessingAsync()
                );
        }
Exemple #4
0
 /// <summary>
 ///		Perform Cmdlet processing.
 /// </summary>
 protected sealed override void ProcessRecord()
 {
     ThreadAffinitiveSynchronizationContext.RunSynchronized(
         () => ProcessRecordAsync()
         );
 }