title: Lazy<T> without exception caching
body: <p>Is there a <code>System.Lazy&lt;T&gt;</code> without exception caching? Or another nice solution for lazy multithreading initialization &amp; caching?</p>
  
  <p>I've got following program (<a href="http://rextester.com/ARKA1785" rel="noreferrer">fiddle it here</a>):</p>
  
  <pre><code>using System;
  using System.Collections.Concurrent;
  using System.Threading;
  using System.Threading.Tasks;
  using System.Net;
  
  namespace ConsoleApplication3
  {
      public class Program
      {
          public class LightsaberProvider
          {
              private static int _firstTime = 1;
  
              public LightsaberProvider()
              {
                  Console.WriteLine("LightsaberProvider ctor");
              }
  
              public string GetFor(string jedi)
              {
                  Console.WriteLine("LightsaberProvider.GetFor jedi: {0}", jedi);
  
                  Thread.Sleep(TimeSpan.FromSeconds(1));
                  if (jedi == "2" &amp;&amp; 1 == Interlocked.Exchange(ref _firstTime, 0))
                  {
                      throw new Exception("Dark side happened...");
                  }
  
                  Thread.Sleep(TimeSpan.FromSeconds(1));
                  return string.Format("Lightsaver for: {0}", jedi);
              }
          }
  
          public class LightsabersCache
          {
              private readonly LightsaberProvider _lightsaberProvider;
              private readonly ConcurrentDictionary&lt;string, Lazy&lt;string&gt;&gt; _producedLightsabers;
  
              public LightsabersCache(LightsaberProvider lightsaberProvider)
              {
                  _lightsaberProvider = lightsaberProvider;
                  _producedLightsabers = new ConcurrentDictionary&lt;string, Lazy&lt;string&gt;&gt;();
              }
  
              public string GetLightsaber(string jedi)
              {
                  Lazy&lt;string&gt; result;
                  if (!_producedLightsabers.TryGetValue(jedi, out result))
                  {
                      result = _producedLightsabers.GetOrAdd(jedi, key =&gt; new Lazy&lt;string&gt;(() =&gt;
                      {
                          Console.WriteLine("Lazy Enter");
                          var light = _lightsaberProvider.GetFor(jedi);
                          Console.WriteLine("Lightsaber produced");
                          return light;
                      }, LazyThreadSafetyMode.ExecutionAndPublication));
                  }
                  return result.Value;
              }
          }
  
          public void Main()
          {
              Test();
              Console.WriteLine("Maximum 1 'Dark side happened...' strings on the console there should be. No more, no less.");
              Console.WriteLine("Maximum 5 lightsabers produced should be. No more, no less.");
          }
  
          private static void Test()
          {
              var cache = new LightsabersCache(new LightsaberProvider());
  
              Parallel.For(0, 15, t =&gt;
              {
                  for (int i = 0; i &lt; 10; i++)
                  {
                      try
                      {
                          var result = cache.GetLightsaber((t % 5).ToString());
                      }
                      catch (Exception e)
                      {
                          Console.WriteLine(e.Message);
                      }
                      Thread.Sleep(25);
                  }
              });
          }
      }
  }
  </code></pre>
  
  <p>Basically I want to cache produced lightsabers, but producing them is expensive and tricky - sometimes exceptions may happen. I want to allow only one producer at time for given <code>jedi</code>, but when exception is thrown - I want another producer to try again. Therefore, desired behavior is like <code>System.Lazy&lt;T&gt;</code> with <code>LazyThreadSafetyMode.ExecutionAndPublication</code> option, but without exceptions caching.</p>
  
  <p>All in all, following technical requirements must be meet:</p>
  
  <ul>
  <li>we want a thread-safe cache</li>
  <li>the cache is a key-value cache. Let's simplify it and the key is type of string and the value is also type of string</li>
  <li>producing an item is expensive - thus production must be started by one and only one thread for given key. Production for key "a" doesn't block production for key "b"</li>
  <li>if production ended in success - we want to cache the produced item</li>
  <li>if during production exception is thrown - we want to pass the exception to the caller. The caller's responsibility is to decide about retry/giving up/logging. Exception isn't cached - next call to the cache for this item will start the item production.</li>
  </ul>
  
  <p>In my example:</p>
  
  <ul>
  <li>we have LightsabersCache, LightsabersCache.GetLightsaber method gets the value for given key</li>
  <li>LightsaberProvider is only a dummy provider. It mimics production nature: the production is expensive (2 seconds), and sometimes (in this case only first time, for key="2") exception is thrown</li>
  <li>the program starts 15 threads and each thread tries 10 times to get the value from range &lt;0;4>. Only one time exception is thrown, so only one time we should see "Dark side happened...". There are 5 keys in the range &lt;0;4> so only 5 "Lightsaber produced" messages should be on the console. We should see 6 times the message "LightsaberProvider.GetFor jedi: x" because one time for each key + one failed for key "2".</li>
  </ul>