C# 来自ThreadLocal的新值<;IDisposable>;在.Value.Dispose()之后
是否有一个内置的C# 来自ThreadLocal的新值<;IDisposable>;在.Value.Dispose()之后,c#,multithreading,idisposable,thread-local,C#,Multithreading,Idisposable,Thread Local,是否有一个内置的ThreadLocal类构造,用于在每个唯一线程内共享一个对象,但如果原始值被释放/破坏/删除/为空,则重新创建该对象 下面是我尝试使用concurrentdirectionary(下面的ThreadLocalDisposable2)实现这种行为的例子,但我希望只使用ThreadLocalDisposable1,但是我无法让Foo测试通过,值。删除(这个)没有达到我希望的效果,仍然会导致ObjectDisposedException public class Class1 {
ThreadLocal
类构造,用于在每个唯一线程内共享一个对象,但如果原始值被释放/破坏/删除/为空,则重新创建该对象
下面是我尝试使用concurrentdirectionary
(下面的ThreadLocalDisposable2
)实现这种行为的例子,但我希望只使用ThreadLocalDisposable1
,但是我无法让Foo
测试通过,值。删除(这个)
没有达到我希望的效果,仍然会导致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();
}
}
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();
}
}
公共类ThreadLocalDisposable1:IDisposable
{
私人溪流(乌富);;
私有静态线程本地线程;
静态ThreadLocalDisposable1()
{
_thread=newthreadlocal(()=>newthreadlocaldisposable1(),true);
}
私有线程LocalDisposable1()
{
_foo=新内存流();
}
公共静态ThreadLocalDisposable1 Get()
{
返回_thread.Value;
}
公共图书馆
{
_foo.WriteByte(1);
}
公共空间处置()
{
//我不认为这意味着什么,我认为这意味着什么
_线程。值。删除(此);
_foo.Dispose();
}
}
[2]
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();
}
}
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();
}
}
公共类ThreadLocalDisposable2:IDisposable
{
私人溪流(乌富);;
私有int_线程;
私有静态ConcurrentDictionary_线程;
静态ThreadLocalDisposable2()
{
_线程=新的ConcurrentDictionary();
}
私有线程LocalDisposable2(int线程)
{
_螺纹=螺纹;
_foo=新内存流();
}
公共静态ThreadLocalDisposable2 Get()
{
返回_threads.GetOrAdd(Thread.CurrentThread.ManagedThreadId,i=>newthreadLocalDisposable2(i));
}
公共图书馆
{
_foo.WriteByte(1);
}
公共空间处置()
{
ThreadLocalDisposable2线程;
_threads.TryRemove(_thread,out thread);
_foo.Dispose();
}
}
编辑:
为了澄清我的意思,基本上我想要ThreadLocal
的所有行为,但是当我调用Dispose
(在本例中,值是ThreadLocalDisposable*
的底层Stream
,而不是静态ThreadLocal
本身)时,将已处理的实例从循环中移除,也就是说,如果再次调用--创建一个新的价值,就好像它是一个全新的线程,需要一个全新的实例
ThreadLocalDisposable1
,[1],是我认为应该有效的示例类,除了.Values之外。Remove(this)
行不会“使其停止流通”,而是强制为该线程创建一个新实例
ThreadLocalDisposable2
,[2],以及ConcurrentDictionary
,是我实现ThreadLocal的一种替代方法,我追求的是“退出流通”行为
编辑:
这不是一个真实的用例,只是一个我能想到的一般示例,但是如果您有一个静态
ThreadLocal
,或者一个套接字,并且它被强制关闭(并在最后一个块中处理)--删除该连接实例,并在再次调用时透明地创建一个新实例。看起来您正在使这一过程变得更加困难。考虑这一点:
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>();
这在功能上似乎相当于您试图使用ConcurrentDictionary
的东西
这就是说,这似乎是另一种更好的管理方式。我不知道你的应用程序,所以我不能确定,但是像
流
或SqlConnection
这样的有状态对象作为全局变量似乎不是个好主意。通常,这些内容是特定于作业的,而不是特定于线程的,因此应该在启动作业时作为参数传递 也许我没有想到,但您使用的是标记为threadlocal的concurrentdictionary吗?@daryal不,我使用的是它,而不是,请参见ThreadLocalDisposable2
。我想使用ThreadLocal
,但我不能完全让它工作,所以我有ConcurrentDictionary
,它可以按照我的要求工作,但感觉有点黑客味。很难想象你在这里想做什么。不过,我建议您创建一个类,其中包含要使其成为可丢弃的对象,并创建该类的ThreadLocal
实例。处理类内的处理/重新创建逻辑,而不是试图管理ThreadLocal
实例的字典。@JimMischel请查看编辑,希望它现在更清晰一些。没有ThreadLocal实例字典。@IlyaKozhevnikov 1。编辑帖子通常比在评论中解释要好。2.你到底想做什么?这听起来是个很糟糕的主意…很有趣。。。具有非静态惰性“singleton”的由内而外的ThreadLocal。。。我没有那样想过。这并不理想,因为它公开了所有的系统线程
内部,而不是对调用方完全透明。我会试一试,看看是否可以将其向后移植,谢谢。我是否正确理解它不是真正处理MyClass
,只是交换了流
,因此尽管在这个简化的示例中,MyClass
有其他数据,例如写入流而不是1的实例字段,这将导致未指定的行为。所以我想说,它在功能上并不等同于concurrentdirectionary
之类的东西。@IlyaKozhevnikov:不,它没有处理MyClass
实例。这就是我的观点:创建一个持久性对象来包装一次性物品。@IlyaKozhevnikovMyClass
只是一个包装器