Description
Verified in .NET 8. In our application, we have an intermittent crash where FileConfigurationProvider throws an IOException when reloading the configuration file. This is easily reproducible by locking the file immediately after saving it, commonly performed by Antivirus software.
E.g.: You will not be able to catch the exception using LoadException:
source.ReloadOnChange = true;
source.ReloadDelay = 10000; // Give us some time to lock the file from some other process...
source.OnLoadException = OnLoadException; // NOT called
Please have a look at FileConfigurationProvider.cs(96). The mistake is obvious. Opening of the stream should be inside the try block!
using Stream stream = OpenRead(file); // Outside try block!
try
{
Load(stream);
}
Exception details
System.AggregateException: A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread. (One or more errors occurred. (The process cannot access the file 'C:\Foo\settings.json' because it is being used by another process.))
---> System.AggregateException: One or more errors occurred. (The process cannot access the file 'C:\Foo\settings.json' because it is being used by another process.)
---> System.IO.IOException: The process cannot access the file 'C:\Foo\settings.json' because it is being used by another process.
at Microsoft.Win32.SafeHandles.SafeFileHandle.CreateFile(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options)
at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
at System.IO.Strategies.FileStreamHelpers.ChooseStrategyCore(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, Int64 preallocationSize)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
at Microsoft.Extensions.Configuration.FileConfigurationProvider.<Load>g__OpenRead|6_0(IFileInfo fileInfo)
at Microsoft.Extensions.Configuration.FileConfigurationProvider.Load(Boolean reload)
at Microsoft.Extensions.Configuration.FileConfigurationProvider.<.ctor>b__1_1()
at Microsoft.Extensions.Primitives.ChangeToken.<>c.<OnChange>b__0_0(Action callback)
at Microsoft.Extensions.Primitives.ChangeToken.ChangeTokenRegistration`1.OnChangeTokenFired()
at Microsoft.Extensions.Primitives.ChangeToken.ChangeTokenRegistration`1.<>c.<RegisterChangeTokenCallback>b__7_0(Object s)
at System.Threading.CancellationTokenSource.Invoke(Delegate d, Object state, CancellationTokenSource source)
at System.Threading.CancellationTokenSource.ExecuteCallbackHandlers(Boolean throwOnFirstException)
--- End of inner exception stack trace ---
at System.Threading.CancellationTokenSource.ExecuteCallbackHandlers(Boolean throwOnFirstException)
at Microsoft.Extensions.FileProviders.Physical.PhysicalFilesWatcher.<>c.<.cctor>b__43_0(Object state)
at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of inner exception stack trace ---
Reproduction Steps
Run attached sample project.
FileConfigurationProviderCrash.zip
Expected behavior
The attached sample project should not throw an IOException.
Actual behavior
IOException is unhandled even though we tell the FileConfigurationSource to ignore exceptions.
Regression?
No response
Known Workarounds
No response
Configuration
No response
Other information
No response
Description
Verified in
.NET 8. In our application, we have an intermittent crash whereFileConfigurationProviderthrows anIOExceptionwhen reloading the configuration file. This is easily reproducible by locking the file immediately after saving it, commonly performed by Antivirus software.E.g.: You will not be able to catch the exception using
LoadException:Please have a look at FileConfigurationProvider.cs(96). The mistake is obvious. Opening of the stream should be inside the
tryblock!Exception details
Reproduction Steps
Run attached sample project.
FileConfigurationProviderCrash.zip
Expected behavior
The attached sample project should not throw an
IOException.Actual behavior
IOExceptionis unhandled even though we tell theFileConfigurationSourceto ignore exceptions.Regression?
No response
Known Workarounds
No response
Configuration
No response
Other information
No response