缓存线程生命周期的数据

时间:2013-06-03 10:36:44

标签: .net multithreading c#-4.0

我正在寻找一种在线程生命周期内缓存数据的方法。不需要跨线程访问数据。

ASP.NET中,您可以使用HttpContext.Current.Items集合执行此操作。只要线程处于活动状态,您就可以保留此处存储的任何内容,并且可以从任何类访问。

我想知道.NET框架(4.0)中是否存在更通用的等价物,它与HTTP无关。??

2 个答案:

答案 0 :(得分:1)

创建具有默认值的ThreadLocal<T>对象后,您可以使用其Value属性获取该值或将其设置为其他值。

您可以根据需要创建任意数量的ThreadLocal<T>个对象,它们可以存储在实例或静态字段中。

Thread.AllocateNamedDataSlot确实在所有线程上分配了一个命名数据槽。但是,每个线程都有自己的这个命名槽的副本,因此它们不会相互干扰。

线程本地存储的目的是为每个线程提供自己的存储位置副本,而不是单独为一个线程创建存储。

线程堆栈上的局部变量实现了后一个目标,只要在线程的执行路径中只有一个方法调用,它就是你真正需要的。

但是,如果线程的执行路径中有多个方法调用,则必须将局部变量从方法传递给方法,这在实践中可能很尴尬。这就是线程本地存储旨在解决的问题。

答案 1 :(得分:1)

您的问题的简单答案是在线程proc中创建缓存。例如:

void MyThreadProc(object state)
{
    var myCache = createDataCache();
    // myCache will available throughout the lifetime of the thread
}

正如您所指出的,如果您的线程包含在单个方法中,那就太棒了。如果必须调用多个方法,则必须将该缓存传递给所有方法。

另一种方法是让线程proc创建一个执行实际处理的类的实例,并让该类拥有缓存。所以你的线程proc看起来像:

void MyThreadProc(object state)
{
    var processor = new ThreadDataProcessor();
    processor.DoProcessing();
}

ThreadDataProcessor构造函数将创建缓存,并且当线程proc退出时将全部处理。如果ThreadDataProcessor需要访问其他数据,则必须将对这些结构的引用传递给构造函数。

线程本地存储有效,但在混合线程本地存储和线程池时必须小心。池线程可以在很长一段时间内(程序的生命周期)挂起,因此线程本地存储可以累积。如果你有很多线程本地数据,这可能会占用相当多的内存。

考虑到所有事情,如果在您的申请中做到合理,我建议采用上述第二种方法。