Я взглянул на код в ThreadLocal<T>
, чтобы увидеть, что делает текущий Dispose
, и он выглядит как вуду.Очевидно, что он избавляется от вещей, связанных с потоками.
Но он не избавляется от значений, если одноразово T
.
Теперь у меня есть решение - класс ThreadLocalDisposables<T>
,но прежде чем дать полное определение, стоит подумать о том, что должно произойти, если вы напишете этот код:
var tl = new ThreadLocalDisposables<IExpensiveDisposableResource>();
tl.Value = myEdr1;
tl.Value = myEdr2;
tl.Dispose();
Должны ли оба myEdr1
& myEdr2
быть утилизированы?Или просто myEdr2
?Или myEdr1
должен быть удален при назначении myEdr2
?
Мне не ясно, какой должна быть семантика.
Однако мне ясно, что если бы я написал этокод:
var tl = new ThreadLocalDisposables<IExpensiveDisposableResource>(
() => new ExpensiveDisposableResource());
tl.Value.DoSomething();
tl.Dispose();
Тогда я ожидал бы, что ресурс, созданный фабрикой для каждого потока, должен быть удален.
Поэтому я не собираюсь разрешать прямое назначение одноразовыхзначение для ThreadLocalDisposables
и разрешить только конструктор фабрики.
Вот ThreadLocalDisposables
:
public class ThreadLocalDisposables<T> : IDisposable
where T : IDisposable
{
private ThreadLocal<T> _threadLocal = null;
private ConcurrentBag<T> _values = new ConcurrentBag<T>();
public ThreadLocalDisposables(Func<T> valueFactory)
{
_threadLocal = new ThreadLocal<T>(() =>
{
var value = valueFactory();
_values.Add(value);
return value;
});
}
public void Dispose()
{
_threadLocal.Dispose();
Array.ForEach(_values.ToArray(), t => t.Dispose());
}
public override string ToString()
{
return _threadLocal.ToString();
}
public bool IsValueCreated
{
get { return _threadLocal.IsValueCreated; }
}
public T Value
{
get { return _threadLocal.Value; }
}
}
Помогает ли это?