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; }
private Collection <PSObject> ExecutePipeline(ExecutionOptions options, Pipeline tempPipeline, Collection <PSObject> collection, out IEnumerable <ErrorRecord> exceptionThrown) { exceptionThrown = new List <ErrorRecord>(); try { bool acquired = Monitor.TryEnter(_runspace); if (!acquired) { return(null); } try { _currentPipeline = tempPipeline; List <ErrorRecord> exception = new List <ErrorRecord>(); 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.AddRange(GetPipelineErrors(options, tempPipeline)); } catch (RuntimeException re) { exception.Add(re.ErrorRecord); } catch (Exception e) { exception.Add(new ErrorRecord(e, e.GetType().FullName, ErrorCategory.NotSpecified, null)); } finally { _currentPipeline = null; } if (exception.Any()) { 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); }