dotnet / dotnet/dotnet-api-docs

Document thread-safety of read-only access for mutable collections

Open
#8,658 12 comments 0 reactions 0 assignees View on GitHub
area-System.Collections Pri3
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.