Aspnetcore.docs: Expand thread safety section with respect to singleton factory

Created on 21 Jun 2018  ยท  6Comments  ยท  Source: dotnet/AspNetCore.Docs

The thread-safety section talks about services:

Thread safety

Singleton services need to be thread safe. If a singleton service has a dependency on a transient service, the transient service may also need to be thread safe depending how it's used by the singleton.

However, it would help to also add a word or two about the thread-safety of a _singleton factory_ when using something like AddSingleton<TService>(IServiceCollection, Func<IServiceProvider,TService>), as in:

c# services.AddSingleton<IFoo>(sp => { // initialization code... return new Foo(/* ... */); });

One would imagine that the factory will be called lazily, when the service is requested for the first time. What happens, though, if multiple threads request the singleton service simultaneously that in turn incurs its initialization?

  1. Does the initialization code run once and run by one thread alone, like a static type constructor?
  2. Does the factory need to be _idempotent_ and so may be called more than once, by more than one thread? The assumption here is that one of those will win (rest discarded) but will effectively return the same result that's used for all subsequent requests.

I'm guessing it's the first case but it would help to clarify in that section. It avoids:

  • people being paranoid and adding locks in their factory code.
  • asking Luke to use The Source. ๐Ÿ˜‰

Document Details

โš  Do not edit this section. It is required for docs.microsoft.com โžŸ GitHub issue linking.

Source - Docs.ms

Most helpful comment

Hello @atifaziz ... I'm working on this topic _TODAY!_ ๐Ÿ˜„

Samples are updated, and I'm getting into the topic content now. I'll get back to you soon.

btw ... My name is "Luke," so rest assured I'll use the Force on this.

All 6 comments

Hello @atifaziz ... I'm working on this topic _TODAY!_ ๐Ÿ˜„

Samples are updated, and I'm getting into the topic content now. I'll get back to you soon.

btw ... My name is "Luke," so rest assured I'll use the Force on this.

... and the Force says to ping @davidfowl ...

@davidfowl, I can wordsmith your answers to questions 1 & 2 for that section of the topic.

btw ... My name is "Luke," so rest assured I'll use the Force on this...and the Force says to ping @davidfowl ...

Thanks for picking this up so quickly! ๐Ÿ’ฏ

Yes initialization code runs once and everything waits on it.

@davidfowl Thanks for the clarification.

Here's a proposal of the section could be expanded:

Thread safety

Singleton services need to be thread safe. If a singleton service has a dependency on a transient service, the transient service may also need to be thread safe depending how it's used by the singleton.

The factory method of single service, such as the second argument to AddSingleton<TService>(IServiceCollection, Func<IServiceProvider,TService>), does not need to be thread-safe. Like a type (static) constructor, it's guaranteed to be called once and by one thread alone.

Thanks ... I'll get this on the PR that I'm putting up ~Monday~ soon (still working on this).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

davisnw picture davisnw  ยท  3Comments

neman picture neman  ยท  3Comments

nenmyx picture nenmyx  ยท  3Comments

AnthonyMastrean picture AnthonyMastrean  ยท  3Comments

Rick-Anderson picture Rick-Anderson  ยท  3Comments