Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to cleanup Configuration related disposables #3564

Closed
JanEggers opened this issue Sep 28, 2018 · 4 comments
Closed

Add ability to cleanup Configuration related disposables #3564

JanEggers opened this issue Sep 28, 2018 · 4 comments

Comments

@JanEggers
Copy link
Contributor

Im having issues in a Unittests that complains that not all threads are ended when the unittest is completed.

Turns out this is due to using this:

 var configuration = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json")
                .AddJsonFile(settingsPath, optional: true, reloadOnChange: true)
                .Build();

the reloadable json file generates Filewatchers that hang in a sleep if the test is ended.

the core problem is that there PhsicalFileProvider is disposable but currently I have to do something like this to clean it up:

foreach (var provider in config.Providers.OfType<JsonConfigurationProvider>())
            {
                if (provider.Source.FileProvider is PhysicalFileProvider pfp)
                {
                    pfp.Dispose();
                }
            }

I see two options here to improve the situation:

  1. make IConfigurationRoot and all related classes disposable so I can just call config.Dispose();

  2. resolve providers from DI so DI takes care of disposing the resources that require to do so.

maybe related to #3110

@JanEggers
Copy link
Contributor Author

update: even after disposing the file providers like above im still having this:

Not Flagged 28660 8 Worker Thread Worker Thread Microsoft.Extensions.Configuration.FileExtensions.dll!Microsoft.Extensions.Configuration.FileConfigurationProvider..ctor.AnonymousMethod__0_1
mscorlib.dll!System.Threading.Thread.Sleep(int millisecondsTimeout)
Microsoft.Extensions.Configuration.FileExtensions.dll!Microsoft.Extensions.Configuration.FileConfigurationProvider..ctor.AnonymousMethod__0_1()
Microsoft.Extensions.Primitives.dll!Microsoft.Extensions.Primitives.ChangeToken.OnChange.AnonymousMethod__0(object s)
mscorlib.dll!System.Threading.CancellationTokenSource.InternalRegister(System.Action callback, object stateForCallback, System.Threading.SynchronizationContext targetSyncContext, System.Threading.ExecutionContext executionContext)
mscorlib.dll!System.Threading.CancellationToken.Register(System.Action callback, object state, bool useSynchronizationContext, bool useExecutionContext)
mscorlib.dll!System.Threading.CancellationToken.Register(System.Action callback, object state)
Microsoft.Extensions.Primitives.dll!Microsoft.Extensions.Primitives.CancellationChangeToken.RegisterChangeCallback(System.Action callback, object state)
Microsoft.Extensions.Primitives.dll!Microsoft.Extensions.Primitives.ChangeToken.OnChange.AnonymousMethod__0(object s)
mscorlib.dll!System.Threading.CancellationTokenSource.InternalRegister(System.Action callback, object stateForCallback, System.Threading.SynchronizationContext targetSyncContext, System.Threading.ExecutionContext executionContext)
mscorlib.dll!System.Threading.CancellationToken.Register(System.Action callback, object state, bool useSynchronizationContext, bool useExecutionContext)
mscorlib.dll!System.Threading.CancellationToken.Register(System.Action callback, object state)
Microsoft.Extensions.Primitives.dll!Microsoft.Extensions.Primitives.CancellationChangeToken.RegisterChangeCallback(System.Action callback, object state)
Microsoft.Extensions.Primitives.dll!Microsoft.Extensions.Primitives.ChangeToken.OnChange.AnonymousMethod__0(object s)
mscorlib.dll!System.Threading.CancellationTokenSource.InternalRegister(System.Action callback, object stateForCallback, System.Threading.SynchronizationContext targetSyncContext, System.Threading.ExecutionContext executionContext)
mscorlib.dll!System.Threading.CancellationToken.Register(System.Action callback, object state, bool useSynchronizationContext, bool useExecutionContext)
mscorlib.dll!System.Threading.CancellationToken.Register(System.Action callback, object state)
Microsoft.Extensions.Primitives.dll!Microsoft.Extensions.Primitives.CancellationChangeToken.RegisterChangeCallback(System.Action callback, object state)
Microsoft.Extensions.Primitives.dll!Microsoft.Extensions.Primitives.ChangeToken.OnChange.AnonymousMethod__0(object s)
mscorlib.dll!System.Threading.CancellationTokenSource.InternalRegister(System.Action callback, object stateForCallback, System.Threading.SynchronizationContext targetSyncContext, System.Threading.ExecutionContext executionContext)
mscorlib.dll!System.Threading.CancellationToken.Register(System.Action callback, object state, bool useSynchronizationContext, bool useExecutionContext)
mscorlib.dll!System.Threading.CancellationToken.Register(System.Action callback, object state)
Microsoft.Extensions.Primitives.dll!Microsoft.Extensions.Primitives.CancellationChangeToken.RegisterChangeCallback(System.Action callback, object state)
Microsoft.Extensions.Primitives.dll!Microsoft.Extensions.Primitives.ChangeToken.OnChange.AnonymousMethod__0(object s)
mscorlib.dll!System.Threading.CancellationTokenSource.InternalRegister(System.Action callback, object stateForCallback, System.Threading.SynchronizationContext targetSyncContext, System.Threading.ExecutionContext executionContext)
mscorlib.dll!System.Threading.CancellationToken.Register(System.Action callback, object state, bool useSynchronizationContext, bool useExecutionContext)
mscorlib.dll!System.Threading.CancellationToken.Register(System.Action callback, object state)
Microsoft.Extensions.Primitives.dll!Microsoft.Extensions.Primitives.CancellationChangeToken.RegisterChangeCallback(System.Action callback, object state)
Microsoft.Extensions.Primitives.dll!Microsoft.Extensions.Primitives.ChangeToken.OnChange.AnonymousMethod__0(object s)
mscorlib.dll!System.Threading.CancellationTokenSource.InternalRegister(System.Action callback, object stateForCallback, System.Threading.SynchronizationContext targetSyncContext, System.Threading.ExecutionContext executionContext)
mscorlib.dll!System.Threading.CancellationToken.Register(System.Action callback, object state, bool useSynchronizationContext, bool useExecutionContext)
mscorlib.dll!System.Threading.CancellationToken.Register(System.Action callback, object state)
Microsoft.Extensions.Primitives.dll!Microsoft.Extensions.Primitives.CancellationChangeToken.RegisterChangeCallback(System.Action callback, object state)
Microsoft.Extensions.Primitives.dll!Microsoft.Extensions.Primitives.ChangeToken.OnChange.AnonymousMethod__0(object s)
mscorlib.dll!System.Threading.CancellationTokenSource.InternalRegister(System.Action callback, object stateForCallback, System.Threading.SynchronizationContext targetSyncContext, System.Threading.ExecutionContext executionContext)
mscorlib.dll!System.Threading.CancellationToken.Register(System.Action callback, object state, bool useSynchronizationContext, bool useExecutionContext)
mscorlib.dll!System.Threading.CancellationToken.Register(System.Action callback, object state)
Microsoft.Extensions.Primitives.dll!Microsoft.Extensions.Primitives.CancellationChangeToken.RegisterChangeCallback(System.Action callback, object state)
Microsoft.Extensions.Primitives.dll!Microsoft.Extensions.Primitives.ChangeToken.OnChange.AnonymousMethod__0(object s)
mscorlib.dll!System.Threading.CancellationTokenSource.InternalRegister(System.Action callback, object stateForCallback, System.Threading.SynchronizationContext targetSyncContext, System.Threading.ExecutionContext executionContext)
mscorlib.dll!System.Threading.CancellationToken.Register(System.Action callback, object state, bool useSynchronizationContext, bool useExecutionContext)
mscorlib.dll!System.Threading.CancellationToken.Register(System.Action callback, object state)
Microsoft.Extensions.Primitives.dll!Microsoft.Extensions.Primitives.CancellationChangeToken.RegisterChangeCallback(System.Action callback, object state)
Microsoft.Extensions.Primitives.dll!Microsoft.Extensions.Primitives.ChangeToken.OnChange.AnonymousMethod__0(object s)
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state)
mscorlib.dll!System.Threading.CancellationCallbackInfo.ExecuteCallback()
mscorlib.dll!System.Threading.CancellationTokenSource.ExecuteCallbackHandlers(bool throwOnFirstException)
mscorlib.dll!System.Threading.CancellationTokenSource.NotifyCancellation(bool throwOnFirstException)
Microsoft.Extensions.FileProviders.Physical.dll!Microsoft.Extensions.FileProviders.Physical.PhysicalFilesWatcher.CancelToken.AnonymousMethod__0()
mscorlib.dll!System.Threading.Tasks.Task.Execute()
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
mscorlib.dll!System.Threading.Tasks.Task.ExecuteWithThreadLocal(ref System.Threading.Tasks.Task currentTaskSlot)
mscorlib.dll!System.Threading.Tasks.Task.ExecuteEntry(bool bPreventDoubleExecution)
mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch()
[Native to Managed Transition]

@Eilon
Copy link
Member

Eilon commented Sep 28, 2018

@JanEggers I think ideally a unit test wouldn't use the "real" configuration and would just use the in-memory configuration provider, thus avoiding all external resources (and thus no file system watchers).

Another option would be for the unit test to just avoid using the reloadOnChange feature.

Are these options in your scenario?

@Eilon
Copy link
Member

Eilon commented Sep 28, 2018

This issue was moved to aspnet/Configuration#882

@dotnet dotnet locked and limited conversation to collaborators Sep 28, 2018
@Eilon Eilon closed this as completed Sep 28, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants