Skip to content

Add net11 Process.ReadAllLines - #590

Merged
SimonCropp merged 1 commit into
mainfrom
process-readalllines
Sep 10, 2026
Merged

Add net11 Process.ReadAllLines#590
SimonCropp merged 1 commit into
mainfrom
process-readalllines

Conversation

@SimonCropp

Copy link
Copy Markdown
Owner

Adds the synchronous counterpart to the already polyfilled ReadAllLinesAsync:

IEnumerable<ProcessOutputLine> ReadAllLines(TimeSpan? timeout = null)

API count 1072 to 1073. This was the last item outstanding from the net11 RC1 sweep.

Semantics

Taken from net11 by driving a child process that writes to both streams with delays between them, rather than assumed:

  • the sequence is lazy. The call returned in 0ms and lines were yielded at 51ms, 755ms and 1458ms as the child produced them, rather than being collected first
  • standard output and standard error are interleaved in arrival order
  • exceeding the timeout throws TimeoutException, matching WaitForExitOrThrow and the other synchronous helpers on Process
  • a process whose output is not redirected throws InvalidOperationException

Implementation

An iterator over the same ConcurrentQueue and SemaphoreSlim arrangement ReadAllLinesAsync already uses, with a blocking wait bounded by the remaining timeout.

Because an iterator body does not run until it is enumerated, the timeout is measured from the point enumeration starts rather than from the call. Recorded as a //Note:.

One gap in the tests

Nothing asserts the TimeoutException path. Provoking it needs a child that stays quiet for a known interval, and every candidate available to the test project either exits promptly or makes the assertion depend on timing, which would be flaky on CI. The path was exercised by hand against net11 with a purpose built child instead. For the same reason there is no test asserting laziness, though that was verified the same way.

The timeout parameter is still covered, with a value large enough not to fire, so the remaining-time arithmetic is exercised.

Verification

  • Solution builds clean in Release. Consume builds clean in Debug across all 22 target frameworks.
  • Tests green on net11.0 (1672), net462 (1638), net8.0 (1669) and net10.0 (1672), plus PublicTests, EmbeddedTests, UnsafeTests, NoRefsTests and NoExtrasTests.
  • Since these tests start real processes, the three new ones were run repeatedly on both net11.0 and net462 to check for timing flakiness. No failures.

Adds the synchronous counterpart to the already polyfilled
ReadAllLinesAsync:

    IEnumerable<ProcessOutputLine> ReadAllLines(TimeSpan? timeout = null)

Semantics were taken from net11 by driving a child process that writes
to both streams with delays between them:

* the sequence is lazy, and lines are yielded as they arrive rather than
  being collected first
* standard output and standard error are interleaved in arrival order
* exceeding the timeout throws TimeoutException, matching the other
  synchronous helpers on Process
* a process without redirected output throws InvalidOperationException

Implemented as an iterator over the same queue and semaphore arrangement
as ReadAllLinesAsync, with a blocking wait bounded by the remaining
timeout. Because an iterator does no work until it is enumerated, the
timeout is measured from the point enumeration starts, which is recorded
as a note.

No test asserts the TimeoutException path. Provoking it needs a child
that stays quiet for a known interval, and every candidate available to
the test project either exits promptly or makes the assertion depend on
timing. The path was exercised by hand against net11 instead.
@SimonCropp SimonCropp added this to the 11.3.0 milestone Sep 10, 2026
@SimonCropp
SimonCropp merged commit 7aeaae5 into main Sep 10, 2026
4 of 6 checks passed
@SimonCropp
SimonCropp deleted the process-readalllines branch September 10, 2026 02:06
This was referenced Sep 10, 2026
This was referenced Sep 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant