Update IConsumerRegister.Default.cs to make dispose thread safe #1438
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Add memory barrier to _disposed field to make Dispose call thread safe
Description:
When doing Integration testing with WebApplicationFactory Class using xunit, tests tear down dispose twice.
One by CancelationToken, with stop method. This first call make CancelationTokenSource disposed, and every thing is fine.
After that WebApplicationFactory is then disposed, and also call ConsumerRegister.Dispose.
Due to race condition, Pulse method is called a second time and try to dispose already disposed CancellationTokenSource.
It seems to be related to dotnet/aspnetcore#40271
Changes:
Affected components:
How to test:
Add an Integration Test project with a WebApplicationFactory, run in Debug mode, exception is logged in Debug output.
Depending your host setup (old fashioned with program and startup class), exception causes test failure with error :
Message:
[Test Collection Cleanup Failure (Data Integration Tests Collection)]: System.ObjectDisposedException : The CancellationTokenSource has been disposed.
CancellationTokenSource.Cancel()
ConsumerRegister.Pulse() line 109
ConsumerRegister.Dispose() line 96
ServiceProviderEngineScope.DisposeAsync()
--- End of stack trace from previous location ---
Host.g__DisposeAsync|16_0(Object o)
Host.DisposeAsync()
Host.Dispose()
WebApplicationFactory
1.DisposeAsync() WebApplicationFactory
1.Dispose(Boolean disposing)WebApplicationFactory`1.Dispose()
Checklist: