Code Changes

Source Changes

6 files modified across Phase 1 (bounded internal waits) and Phase 2 (Invoke/Stop public API).

6 files +174 lines −20 lines
01

Modified Files

30s runspace-open wait, new StopPipelines(TimeSpan) parallel overload, waitAllIsDone bounded to 30s

+37 / −5 REQ-06

30s close wait, 30s job stop wait, Dispose() catches TimeoutException and forces Broken state

+28 / −2 REQ-08

PipelineFinishedEvent.WaitOne bounded to 30s in Stop()

+6 / −1 REQ-07

PSInvocationSettings.Timeout property, Stop(TimeSpan) overload, Phase 2 bounded Invoke path, pool acquisition timeout, batch timeout, internal stop wait

+91 / −5 REQ-01REQ-02REQ-02aREQ-03REQ-04REQ-05

Added OperationTimedOut and StopTimedOut localizable error message strings

+7 / −0 REQ-02REQ-04REQ-05

Added StopPipelinesTimedOut localizable error message string

+4 / −0 REQ-06REQ-07REQ-08
02

Before / After

PowerShell.Invoke() — single runspace (Phase 2)
before
_worker.CreateRunspaceIfNeededAndDoWork(rsToUse, true);
after
if (timeout == InfiniteTimeSpan) {
  _worker.CreateRunspaceIfNeededAndDoWork(rsToUse, true);
} else {
  var task = Task.Run(() => _worker.CreateRunspaceIfNeededAndDoWork(...));
  if (!task.Wait(timeout)) { CoreStop(); throw new TimeoutException(...); }
}
RunspacePool acquisition (PowerShell.cs)
before
_worker.GetRunspaceAsyncResult.AsyncWaitHandle.WaitOne();
after
if (!...AsyncWaitHandle.WaitOne(poolTimeout))
  throw new TimeoutException(...);
BatchInvocationContext wait
before
context.Wait();
after
if (timeout == InfiniteTimeSpan)
  context.Wait();
else
  context.Wait(batchTimeout);
LocalPipeline.Stop() finish wait
before
PipelineFinishedEvent.WaitOne();
after
if (!PipelineFinishedEvent.WaitOne(TimeSpan.FromSeconds(30)))
  throw new TimeoutException(...);
StopPipelines() — sequential (ConnectionBase.cs)
before
for (int i = len-1; i >= 0; i--)
  runningPipelines[i].Stop();
after
Task[] tasks = pipelines.Select(p => Task.Run(() => p.Stop())).ToArray();
if (!Task.WaitAll(tasks, timeout))
  throw new TimeoutException(...);
LocalConnection.Dispose() — Close call
before
Close();
after
try { Close(); }
catch (TimeoutException te) {
  SetRunspaceState(RunspaceState.Broken, te);
}