Lazy с LazyThreadSafeMode.PublicationOnly и IDisposable

Сегодня я играл с Lazy и нашел интересный случай (на мой взгляд).

http://msdn.microsoft.com/en-us/library/system. threading.lazythreadsafetymode.aspx

  • PublicationOnly:

    Когда несколько потоков пытаются одновременно инициализировать отложенный экземпляр, всем потокам разрешается запускать метод инициализации ... Любые экземпляры T, созданные конкурирующими потоками, отбрасываются.

    Если мы посмотрим на код Lazy .LazyInitValue (), мы обнаружим, что нет никакой проверки для реализации IDisposable, и здесь могут просочиться исправления:

      case LazyThreadSafetyMode.PublicationOnly: 
    
    

    Когда несколько потоков пытаются инициализировать экземпляр Lazy одновременно, всем потокам разрешается запускать метод инициализации ... Любые экземпляры T, созданные конкурирующими потоками, отбрасываются.

    Если мы посмотрим на код Lazy .LazyInitValue (), мы обнаружим, что нет никакой проверки для реализации IDisposable, и здесь могут просочиться исправления:

      case LazyThreadSafetyMode.PublicationOnly: 
    
    

    Когда несколько потоков пытаются инициализировать экземпляр Lazy одновременно, всем потокам разрешается запускать метод инициализации ... Любые экземпляры T, созданные конкурирующими потоками, отбрасываются.

    Если мы посмотрим на код Lazy .LazyInitValue (), мы обнаружим, что нет никакой проверки для реализации IDisposable, и здесь могут быть утечки ресурсов:

      case LazyThreadSafetyMode.PublicationOnly:
     в коробке = this.CreateValue ();
     if (Interlocked.CompareExchange (ссылка this.m_boxed, boxed, null)! = null)
     { 
    // * boxed.Dispose (); -> см. ниже.
     в коробке = (В коробке ) this.m_boxed;
     }
     сломать;
    

На данный момент единственный способ гарантировать, что создается только экземпляр, - это использовать LazyThreadSafetyMode.ExceptionAndPublication .

Итак, у меня есть 2 вопроса:

  • Я что-то пропускаю или мы это видим Может быть создано несколько экземпляров, и в этой ситуации может произойти утечка ресурсов?
  • Если это правильное предположение, почему бы не проверить наличие IDisposable в этой ситуации и не реализовать Dispose () в штучной упаковке , чтобы делегировать удаление в экземпляр в штучной упаковке T , если он реализует IDisposable, или каким-либо другим способом:

      class Boxed 
     {
     внутренний T m_value;
     void Dispose ()
     {
     если (m_value - IDisposable)
    {((IDisposable) m_value) .Dispose (); }
     }
     }
    

7
задан Andrey Taptunov 15 May 2011 в 11:06
поделиться