Skip to content

Modernize to .NET 10, fix latent thread synchronization related Race conditions#182

Open
amirburbea wants to merge 9 commits intomicrosoft:masterfrom
amirburbea:modernize-net10
Open

Modernize to .NET 10, fix latent thread synchronization related Race conditions#182
amirburbea wants to merge 9 commits intomicrosoft:masterfrom
amirburbea:modernize-net10

Conversation

@amirburbea
Copy link

@amirburbea amirburbea commented Mar 24, 2026

Using @adam-dot-cohen's PR as a base, update all libraries to net10.0, but remove the dotnet standard library references (i.e. Microsoft.CSharp).

Fixed locking in ConfigModifier to support re-entry
Fixed race condition in BinaryPipe
Use newer Assert methods in test libraries

@microsoft-github-policy-service agree

adam-dot-cohen and others added 6 commits December 2, 2022 04:44
2. Workaround to windows only thread affinity in Native32 for Linux

3. Solution updated to target Net7, Net6, Net472, and NetCoreapp3.1
- Upgraded MSTest packages with security vulerabilites
- Reverted StyleCop package update from previous commit
- Target net8.0 across all projects, dropping net6.0/net7.0/net472
- Remove legacy .NET Standard packages (System.Linq.Expressions 4.3.0,
  Microsoft.CSharp 4.7.0, System.Diagnostics.*, etc.) now built into the runtime
- Upgrade Microsoft.CodeAnalysis.Scripting 4.4.0 -> 5.3.0
- Upgrade MSTest 3.x -> 4.x, System.Reactive 5.x -> 6.x, and other packages
- Fix ConfigModifier gate: replace Monitor (thread-affine) with SemaphoreSlim +
  AsyncLocal depth counter, making it safe for async tests that release from a
  different thread while remaining re-entrant for nested Modify() calls
- Make T4 template import conditional so dotnet CLI builds work without VS
- Add trill.runsettings with StopRunOnFirstFailure for faster test diagnosis
- All 3185 tests pass on .NET 8
…er concurrent scheduling

When both inputs complete concurrently, ProcessPendingBatches() uses Monitor.TryEnter
and silently returns if another thread holds the lock. The subsequent Monitor.Enter block
then called base.OnCompleted() immediately, propagating completion downstream before
queued batches were processed. Fixed by calling ProcessPendingBatches() inside the
Monitor.Enter block before base.OnCompleted() - Monitor is reentrant so TryEnter
succeeds for the owning thread, guaranteeing all pending batches are flushed first.
…on tree compat

- Target net10.0 across all projects
- Remove StyleCop from core library (was never running on net8 due to netstandard2.0 condition)
- Standardize test projects on StyleCop 1.1.118
- Suppress SA1137 in test ruleset (T4-generated files have non-standard indentation)
- Fix AdHocTests: string.Join with params object[] instead of params ReadOnlySpan<object>
  to avoid CS8640/CS9226 in expression trees under .NET 10
@amirburbea
Copy link
Author

@amirburbea please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.

@microsoft-github-policy-service agree [company="{your company}"]

Options:

  • (default - no company specified) I have sole ownership of intellectual property rights to my Submissions and I am not making Submissions in the course of work for my employer.
@microsoft-github-policy-service agree
  • (when company given) I am making Submissions in the course of work for my employer (or my employer has intellectual property rights in my Submissions by contract or applicable law). I have permission from my employer to make Submissions and enter into this Agreement on behalf of my employer. By signing below, the defined term “You” includes me and my employer.
@microsoft-github-policy-service agree company="Microsoft"

Contributor License Agreement

@microsoft-github-policy-service agree

BinaryDecoder:
- DecodeFloat, DecodeDouble, DecodeGuid, ReadIntFixed: replace new byte[]
  with stackalloc Span<byte>; add Span<byte> overload of ReadAllRequiredBytes
- DecodeString: bypass DecodeByteArray, rent from ArrayPool<byte>, decode
  string, return buffer — avoids a heap allocation per string field

BinaryEncoder:
- Encode(float): replace BitConverter.GetBytes (allocates) with stackalloc +
  BitConverter.TryWriteBytes
- Encode(Guid): replace ToByteArray() (allocates) with stackalloc +
  TryWriteBytes
- Encode(string): replace Encoding.UTF8.GetBytes(string) (allocates) with
  ArrayPool<byte> rent, encode into span, delegate to Encode(ReadOnlySpan<byte>)
The codegen cache (EquiJoinStreamable.cachedPipes) persisted across tests
in the same process, causing JoinTestWithException to silently succeed
(no exception thrown) when a compatible join had already been compiled
by an earlier test.

Fix: add internal Clear() to SafeConcurrentDictionary, expose cachedPipes
as internal on EquiJoinStreamable, and clear the exact cache instance in
[TestInitialize] before each run. The test now uses a named JoinResult
struct so the closed generic type can be referenced at compile time, and
asserts the StreamProcessingException is always thrown.
@adam-dot-cohen
Copy link

Great! Thanks

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.

2 participants