2

How to use Lazy(Func<T> valueFactory) of C# in such a way that, if initialization fails, it should not use cached Exception and at the same time it should not run multiple threads for initialization?

If I use LazyThreadSafetyMode.PublicationOnly as a second parameter, then it will run multiple threads for initialization on start and throws exceptions from all threads if exception occurs in initialization. But if I use LazyThreadSafetyMode.ExecutionAndPublication as a second parameter it will cache the exception and rethrow the same and never reinitialize it again.

I need a pattern/version where it should run on single thread for initialization and should not cache exceptions.

I can't use constructor version as I have to conditionally create different instances of T on the basis of some parameters set at runtime,

I am using Lazy<TInterface>(func()) and conditionally returning different implementations.

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
usFarswan
  • 193
  • 2
  • 10
  • The docs for [LazyThreadSafetyMode.ExecutionAndPublication](https://learn.microsoft.com/en-us/dotnet/api/system.threading.lazythreadsafetymode) say _"If you use a `Lazy` constructor that does not specify an initialization method, **exceptions that are thrown by the parameterless constructor for `T` are not cached**"_ - and goes on to say - _"When you specify .. ExecutionAndPublication, [exception] caching depends on whether you specify an initialization method or allow the parameterless constructor for T to be used"_ - so the answer depends on what's being initialized. – stuartd Aug 12 '20 at 15:38
  • Hi @stuartd: Here I can't use Constructor version as I have to conditionally create different instances of T, I am using Lazy(func()) and conditionally returning different implementations on the basis of some parameters set at runtime. I have also updated description above. – usFarswan Aug 12 '20 at 15:48
  • So it sounds like the problem you're facing is that this is 'by design' - _"If you use a `Lazy` constructor that specifies an initialization method (valueFactory parameter), and if that initialization method throws an exception (or fails to handle an exception) the first time you call the Value property, then the exception is cached and thrown again on subsequent calls to the Value property."_ – stuartd Aug 12 '20 at 15:53
  • 2
    @usFarswan post your actual code please, don't describe it. Why would the factory method *throw* in the first place? Are you trying to use exceptions as switches? – Panagiotis Kanavos Aug 12 '20 at 15:54
  • As far as I know, the (uncommon) behavior your are looking for cannot be achieved with the `Lazy` class. You would need to implement it yourself – Manuel Allenspach Aug 12 '20 at 15:57
  • @stuartd: Yes you are correct, – usFarswan Aug 12 '20 at 15:57
  • @Panagiotis Kanavos : Factory method is actually creating a SQL Connection and opening it, so sometimes when SQL Server is down then in that case init fails and hence later on exception re-throws, – usFarswan Aug 12 '20 at 16:00

0 Answers0