.net 使用具有ThreadStatic属性的并行扩展。它会泄漏内存吗?

.net 使用具有ThreadStatic属性的并行扩展。它会泄漏内存吗?,.net,parallel-extensions,thread-static,.net,Parallel Extensions,Thread Static,我大量使用并行扩展,我刚刚遇到了一个案例,使用线程本地存储允许工作线程重用对象可能是明智的。因此,我正在查看ThreadStatic属性,该属性将静态字段/变量标记为每个线程具有唯一值 在我看来,在不保证PE重用线程的情况下,使用带有ThreadStatic属性的PE是不明智的。也就是说,如果线程在某种程度上被创建和销毁,那么变量(以及它们指向的对象)是否会在线程本地存储中保留一段不确定的时间,从而导致内存泄漏?或者线程存储被绑定到线程,并在线程被释放时被释放?但是,池中仍然可能有线程,这些线程

我大量使用并行扩展,我刚刚遇到了一个案例,使用线程本地存储允许工作线程重用对象可能是明智的。因此,我正在查看ThreadStatic属性,该属性将静态字段/变量标记为每个线程具有唯一值

在我看来,在不保证PE重用线程的情况下,使用带有ThreadStatic属性的PE是不明智的。也就是说,如果线程在某种程度上被创建和销毁,那么变量(以及它们指向的对象)是否会在线程本地存储中保留一段不确定的时间,从而导致内存泄漏?或者线程存储被绑定到线程,并在线程被释放时被释放?但是,池中仍然可能有线程,这些线程的生命周期很长,并且从线程用于的各种代码片段中积累线程本地存储

是否有更好的方法使用PE获取线程本地存储


谢谢。

编辑:根据汉斯的回答,听起来TLS实际上无论如何都会被清理干净。。。这就留下了一点答案:


您真的没有更好的方法在线程中重用值吗?如果有两个任务使用相同的线程(一个完成,然后运行另一个),那么它们真的需要相同的值吗?实际上,您只是将此作为一种避免在任务中以更可控的方式传播数据的方法吗?

我强烈建议对线程本地存储使用正常模式,如本文所述


使用[ThreadStatic]时,重要的是threadpool线程在终止时是否清理TLS变量。MSDN文档中没有任何建议表明它没有。实现起来并不困难,它只需要调用TlsFree()API函数。我编写了一个小测试应用程序,没有任何泄漏的证据。

正确的术语是“失效”而不是“销毁”线程从池中移除,然后从堆栈中洗牌。该场景模拟了一个基于网格的“世界”——独立评估所述世界中的一组代理。因此,为了并行运行,我可以在每个并行循环中创建一个新世界、使用和丢弃。我的意图是在世界上放置Reset()方法以允许重用。我想静态本地存储可以让我不必管理自己的“世界”池,也不用对池进行关联的线程锁定访问等。@locster:恐怕我仍然看不到线程本地存储的好处。如果它在一个任务中,为什么不保留引用呢?每次评估都会将一个代理单独放入一个世界。因此,如果我有8个CPU内核/线程,我在任何给定时间都有8个独立的世界被模拟——每个线程一个世界。@locster:但是你不也有8个代理吗?如果是这样的话,为什么代理不应该了解这个世界,而不是依赖线程本地存储?@locster:如果你已经在使用并行扩展,那么你大概已经有了
ConcurrentBag
,如果你知道需要多少,它可以充当一个池。每个代理需要多长时间?两次获取锁(一次从池中检索世界,一次返回世界)的成本将是微不足道的,除非代理也在做微不足道的工作。