Exemplo n.º 1
0
        private Collection<PSObject> ExecutePipeline(ExecutionOptions options, Pipeline tempPipeline,
                                                     Collection<PSObject> collection, out IEnumerable<ErrorRecord> exceptionThrown)
        {
            exceptionThrown = null;
            try
            {
                bool acquired = Monitor.TryEnter(_runspace);
                if (! acquired)
                {
                    return null;
                }

                try
                {
                    _currentPipeline = tempPipeline;

                    IEnumerable<ErrorRecord> exception = null;
                    try
                    {
                        WaitWhileRunspaceIsBusy();

                        tempPipeline.StateChanged += OnPipelineStateChange;
                        try
                        {
                            ExecutePipeline(options, tempPipeline);
                        }
                        catch (PSInvalidOperationException ioe)
                        {
                            /*
                             * HACK: there seems to be some lag between the toggle of the runspace
                             * availability state and the clearing of the runspace's current
                             * pipeline state.  it's possible for the runspace to report it's available
                             * for use and then raise a PSInvalidOperationException indicating that another
                             * pipeline is currently executing.
                             * 
                             * This is a hacky way around the issue - wait 1/3 of a second for the 
                             * runspace state to clear and try again.
                             * 
                             * I've also tried adding a WaitWhilePipelineIsRunning method that spins
                             * on a DoWait while the pipeline is not in the completed or failed state;
                             * however this seems to slow the execution down considerably.  
                             */
                            if (tempPipeline.PipelineStateInfo.State == PipelineState.NotStarted)
                            {
                                Thread.Sleep(333);
                                ExecutePipeline(options, tempPipeline);
                            }
                        }
                        tempPipeline.Input.Close();

                        // WaitWhilePipelineIsRunning(tempPipeline);                    

                        collection = tempPipeline.Output.ReadToEnd();
                        if (null != tempPipeline.PipelineStateInfo.Reason)
                        {
                            throw tempPipeline.PipelineStateInfo.Reason;
                        }
                        exception = GetPipelineErrors(options, tempPipeline);
                    }
                    catch( RuntimeException re )
                    {
                        exception = new ErrorRecord[]{re.ErrorRecord};
                    }
                    catch( Exception e )
                    {
                        exception = new ErrorRecord[]
                                        {
                                            new ErrorRecord( e, e.GetType().FullName, ErrorCategory.NotSpecified, null), 
                                        };
                    }
                    finally
                    {
                        _currentPipeline = null;
                    }

                    if (null != exception)
                    {
                        if (!options.HasFlag(ExecutionOptions.DoNotRaisePipelineException))
                        {
                            exception.ToList().ForEach( RaisePipelineExceptionEvent );
                        }
                        exceptionThrown = exception;
                    }
                }
                finally
                {
                    Monitor.Exit(_runspace);
                }
            }
            catch (Exception ex)
            {
                exceptionThrown = new ErrorRecord[]
                                        {
                                            new ErrorRecord( ex, ex.GetType().FullName, ErrorCategory.NotSpecified, null), 
                                        };
            }
            return collection;
        }