Сегодня я играл с 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 (); }
}
}