New value from ThreadLocal<IDisposable> after .Value.D
本文关键字:gt after Value IDisposable lt value from ThreadLocal New | 更新日期: 2023-09-27 18:10:10
是否有一个内置的ThreadLocal<T>
类结构共享对象在每个唯一的线程,但重新创建它,如果原始值被处置/销毁/撕下/空?
这是我在ConcurrentDictionary
(下面的ThreadLocalDisposable2
)实现这种行为的尝试,但我希望只是使用ThreadLocal<T>
(如ThreadLocalDisposable1
),但是我不能得到Foo
测试通过,.Values.Remove(this)
不做我希望它会做的事情,仍然导致ObjectDisposedException
。
public class Class1
{
[Test]
public void Foo()
{
using (var foo = ThreadLocalDisposable1.Get())
foo.Foo();
using (var foo = ThreadLocalDisposable1.Get())
foo.Foo();
}
[Test]
public void Bar()
{
using (var bar = ThreadLocalDisposable2.Get())
bar.Foo();
using (var bar = ThreadLocalDisposable2.Get())
bar.Foo();
}
}
[1]
public class ThreadLocalDisposable1 : IDisposable
{
private Stream _foo;
private static ThreadLocal<ThreadLocalDisposable1> _thread;
static ThreadLocalDisposable1()
{
_thread = new ThreadLocal<ThreadLocalDisposable1>(() => new ThreadLocalDisposable1(), true);
}
private ThreadLocalDisposable1()
{
_foo = new MemoryStream();
}
public static ThreadLocalDisposable1 Get()
{
return _thread.Value;
}
public void Foo()
{
_foo.WriteByte(1);
}
public void Dispose()
{
//I do not think it means what I think it means
_thread.Values.Remove(this);
_foo.Dispose();
}
}
[2]
public class ThreadLocalDisposable2 : IDisposable
{
private Stream _foo;
private int _thread;
private static ConcurrentDictionary<int, ThreadLocalDisposable2> _threads;
static ThreadLocalDisposable2()
{
_threads = new ConcurrentDictionary<int, ThreadLocalDisposable2>();
}
private ThreadLocalDisposable2(int thread)
{
_thread = thread;
_foo = new MemoryStream();
}
public static ThreadLocalDisposable2 Get()
{
return _threads.GetOrAdd(Thread.CurrentThread.ManagedThreadId, i => new ThreadLocalDisposable2(i));
}
public void Foo()
{
_foo.WriteByte(1);
}
public void Dispose()
{
ThreadLocalDisposable2 thread;
_threads.TryRemove(_thread, out thread);
_foo.Dispose();
}
}
编辑:只是为了澄清我的意思,基本上我想要ThreadLocal
的所有行为,但是当我调用Dispose
时(在这个例子中,ThreadLocalDisposable*
在这个例子中具有底层Stream
,而不是静态ThreadLocal
本身),将处置的实例从循环中取出,即如果再次调用-创建一个新值,就好像它是一个全新的线程需要一个全新的实例。
ThreadLocalDisposable1
, [1],是我认为应该工作的样例类,除了.Values.Remove(this)
行没有"将其从循环中取出"并强制为该线程创建一个新实例。
ThreadLocalDisposable2
, [2]与ConcurrentDictionary
一起,是我实现ThreadLocal的替代方法,具有我所追求的"退出循环"行为。
这不是一个真正的用例我有,只是一个一般的例子,我能想到的,但如果你有一个静态的ThreadLocal<SqlConnection>
,或套接字,它被强制关闭(并处置在最后块)-删除该连接实例,并创建一个新的透明,如果再次调用
看起来你把这件事弄得比本来更困难了。想想看:
public class MyClass: IDisposable
{
private Stream _foo;
public MyClass Get()
{
if (_foo == null)
{
_foo = new MemoryStream();
}
}
public void Foo()
{
_foo.WriteByte(1);
}
public void Dispose()
{
if (_foo != null)
{
_foo.Dispose();
_foo = null;
}
}
}
现在,您可以创建其中一个:
ThreadLocal<MyClass> MyThing = new ThreadLocal<MyClass>();
你可以写:
using (MyThing.Value.Get())
{
// do stuff
}
这似乎在功能上等同于你试图用ConcurrentDictionary
做的事情。
也就是说,这似乎是另一种更好的管理方式。我不知道你的应用程序,所以我不能肯定地说,但它似乎是一个坏主意,有一个有状态的对象,如Stream
或SqlConnection
作为一个全局变量。通常这些东西是特定于作业的,而不是特定于线程的,因此应该在启动作业时作为参数传递。