dotnet / dotnet/dotnet-api-docs
Document thread-safety of read-only access for mutable collections
- Dominant language
- C#
- Stars
- 949
- Forks
- 1.7k
- Avg merge
- 3d 27m
- Merged PRs (30d)
- 49
Description
### Is there an existing issue for this?
- [X] I have searched the existing issues
### Describe the bug
Options use caching, for example:
https://github.com/dotnet/runtime/blob/e2c0735927642a11162c0d12799be2921bd1c984/src/libraries/Microsoft.Extensions.Options/src/UnnamedOptionsManager.cs#L25
Since [`TOptions` are registered at the singleton scope](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-7.0#options-interfaces), any two DI participants (e.g. controller instances) may receive the same `TOptions` instance when they retrieve it using `IOptions.Value`.
This means that any user of the Options class must assume concurrent access to the classes' members. Now, for most boundable types (like `string` or `int`) this won't be an issue. However, for collection types, this potentially becomes more complicated. Even if the first thing I do is store a `IOptions.Value.ToImmutableArray()` , this still incurs enumeration. It is not clear to me that all boundable collection types are thread safe even for read-only enumeration of the original collection in the shared `TOptions` class. And while I suspect [arrays possess this property](https://learn.microsoft.com/en-us/dotnet/api/system.array?view=net-7.0#thread-safety), I do not see any such mention for e.g. [`HashSet`](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.hashset-1?view=net-7.0).
### Expected Behavior
Guarantee at the ASP.NET level that all boundable Options collection types are thread safe for concurrent enumeration. For example, if `HashSet` does not provide this guarantee, you could create a subclass of it that does provide it, and inject it into bound `TOptions` classes.
### Steps To Reproduce
```cs
public class MyOptions { HashSet MySet {get; set;} }
public class MyController
{
public MyController(IOptions options)
{
foreach (string s in options.Value.MySet) { Console.WriteLine(s); }
}
}
```
### Exceptions (if any)
In theory, things like `NullReferenceException` or similar unexpected exceptions when non thread safe operations are performed.
### .NET Version
6.0.403
### Anything else?
In case I'm wrong and all boundable collections are thread safe for readonly enumeration, I believe it should be specified clearly in all the relevant documentation pages. I guess in that case that would be more of a dotnet docs bug, but considering the aforementioned singleton registration of `IOptions` I think it's something you should address in your docs too.
Contributor guide
Assessment
This issue has not been assessed yet.