You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
refactor!: remove v3 binary-compatibility shims for TUnit (#372)
TUnit no longer depends on EnumerableAsyncProcessor, so the members kept
solely so TUnit.Engine (compiled against v3) could bind at runtime are
no longer needed:
- Remove redundant ProcessInParallel(int maxConcurrency) shims from the
four builder classes; int arguments still resolve to the
ProcessInParallel(int?, bool) overload.
- Remove the obsolete no-selector
AsyncEnumerableExtensions.ProcessInParallel<T>(IAsyncEnumerable<T>,
CancellationToken) collect-only overload.
- Delete V3BinaryCompatibilityTests and the corresponding
PublicAPI.Shipped.txt entries (v4 is not yet tagged, so the surface
never shipped).
- Drop the TUnit coupling notes from CLAUDE.md and the README migration
guide.
TUnit test projects compile to executables; VSTest-style `dotnet test --filter` does not work. See the `tunit-testing` skill for full filter syntax.
31
31
32
-
**TUnit itself depends on this library.**`TUnit.Engine` is compiled against EnumerableAsyncProcessor v3, and the locally built assembly shadows the copy TUnit shipped with (same assembly identity), so removing or changing a public member that TUnit.Engine binds to crashes test discovery with `MissingMethodException` before any test runs. The exact signatures TUnit needs are pinned by `V3BinaryCompatibilityTests` and marked as binary-compat members in the source — do not remove them until TUnit ships a build compiled against v4.
33
-
34
32
CI (`.github/workflows/dotnet.yml`) runs the `EnumerableAsyncProcessor.Pipeline` project (a ModularPipelines app, `dotnet run -c Release` from that directory), which builds, tests, packs, and — on `main` — publishes to NuGet. Versioning comes from GitVersion (`GitVersion.yml` pins `next-version: 4.0.0`; keep that file present, its absence makes ModularPipelines generate a Mainline config that crashes on GitHub PR merge commits).
Copy file name to clipboardExpand all lines: EnumerableAsyncProcessor/Extensions/AsyncEnumerableExtensions.cs
-20Lines changed: 0 additions & 20 deletions
Original file line number
Diff line number
Diff line change
@@ -150,26 +150,6 @@ public static async IAsyncEnumerable<TOutput> SelectManyAsync<T, TOutput>(
150
150
}
151
151
}
152
152
153
-
/// <summary>
154
-
/// Collects every item from the source into a list. This overload has no work to parallelize;
155
-
/// it is kept for binary compatibility with assemblies compiled against v3 (notably TUnit).
156
-
/// </summary>
157
-
[Obsolete("This overload only collects the stream and parallelizes nothing. Pass a selector, or enumerate the stream directly. It exists for binary compatibility with assemblies compiled against v3.")]
Copy file name to clipboardExpand all lines: README.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -26,7 +26,7 @@ Version 4 is a major release. Review these source and behaviour changes before u
26
26
27
27
-**.NET 8 is the minimum runtime.** The `net6.0` and `netstandard2.0` targets, the Polyfill dependency, and the `TaskCompletionSource` compatibility shim were removed. The package targets and tests `net8.0`, `net9.0`, and `net10.0`.
28
28
-**Parallel processing has one API.** Use `ProcessInParallel(maxConcurrency: 100)` for bounded concurrency and `ProcessInParallel()` for unbounded concurrency. The old non-timed `RateLimitedParallelAsyncProcessor*` types and duplicate overload family were removed. Rename named `levelOfParallelism` arguments to `maxConcurrency` on the `ProcessInParallel` builder family (`InParallelAsync` keeps its `levelOfParallelism` parameter name); replace positional `ProcessInParallel(true)` calls with `ProcessInParallel(scheduleOnThreadPool: true)`.
29
-
-**The parameterized no-selector `IAsyncEnumerable<T>.ProcessInParallel(maxConcurrency, ...)` overloads were removed.** They only buffered the stream into a list — their `maxConcurrency`/`scheduleOnThreadPool` parameters had no effect. Pass a selector (`items.ProcessInParallel(item => Task.FromResult(item), maxConcurrency)`) instead. The parameterless `ProcessInParallel(cancellationToken)` overload remains for binary compatibility with v3-compiled assemblies (notably TUnit) and is documented as a plain collect.
29
+
-**The no-selector `IAsyncEnumerable<T>.ProcessInParallel(...)` overloads were removed.** They only buffered the stream into a list — their `maxConcurrency`/`scheduleOnThreadPool` parameters had no effect. Pass a selector (`items.ProcessInParallel(item => Task.FromResult(item), maxConcurrency)`) instead, or enumerate the stream directly.
30
30
-**`IAsyncEnumerableProcessor` moved to `EnumerableAsyncProcessor.Interfaces`** (previously `EnumerableAsyncProcessor.Extensions`) and now implements `IAsyncDisposable`/`IDisposable`. Processors returned by the `IAsyncEnumerable<T>` builder path dispose their internal resources automatically when `ExecuteAsync` completes; they are single-use.
31
31
-**Processor and builder classes are sealed.** None of them were externally subclassable in practice (their pipelines hinge on internal members); v4 makes that explicit.
32
32
-**Timed processing is a real start-rate limit.** It now uses a shared token bucket instead of holding each worker slot for at least one window. `ProcessInParallel(permitsPerWindow, window, maxConcurrency)` controls start rate and in-flight concurrency independently. The existing two-argument overload remains and uses its first value for both limits.
0 commit comments