在线程中设置全局变量 - C#

Arl*_*ler 23 c# .net-4.0 thread-safety

我有一个HTTP服务器,我正在使用HTTP侦听器编写,我想以某种方式声明某些变量可以从一个线程内的任何地方访问.

  • 我的webserver类是基于实例的,所以我不能真正使用静态变量.
  • 我可以使用实例变量,因为所有代码都在一个类中,但是......我不知道.

我想过使用字典:Dictionary</*[type of Thread ID here]*/,ThreadData>但是我担心可能存在线程问题.ThreadData可能是一个类的实例,但我可能会使用一个结构,取决于哪个会更有效.

  • 如果我将字典键入线程ID并对其进行编程,以便一个线程在字典中询问自己的条目,那么在访问字典时是否会出现与线程相关的问题?
  • 每个线程都会添加自己的条目.在添加新的线程项时,我是否必须锁定字典?如果是这样,我是否能够使用单独的锁对象来允许线程同时访问自己的数据?

使用并发字典会有优势吗?还有另一种更安全的线程方式吗?

我目前正在使用ThreadPool.QueueUserWorkItem.我不确定这会为每个项目使用一个新线程.如果没有,那么我也可以将它键入上下文.

更新:根据ThreadPool类 - MSDN,它确实重用了线程.它并没有清除线程数据.

当线程池重用线程时,它不会清除线程本地存储中或使用ThreadStaticAttribute属性标记的字段中的数据.因此,当方法检查线程本地存储或使用ThreadStaticAttribute属性标记的字段时,它找到的值可能会从先前使用的线程池线程中遗留下来.

ken*_*n2k 34

一种解决方案是使用公共静态字段,其ThreadStatic属性为:

[ThreadStatic]
public static int ThreadSpecificStaticValue;
Run Code Online (Sandbox Code Playgroud)

标记为ThreadStaticAttribute的静态字段不在线程之间共享.每个执行线程都有一个单独的字段实例,并独立设置和获取该字段的值.如果在另一个线程上访问该字段,则它将包含不同的值.


Gen*_*ene 6

您可以使用线程类的内置存储机制:

public class Program
{
  private static LocalDataStoreSlot _Slot = Thread.AllocateNamedDataSlot("webserver.data");

  public static void Main(string[] args)
  {
    var threads = new List<Thread>();

    for (int i = 0; i < 5; i++)
    {
      var thread = new Thread(DoWork);
      threads.Add(thread);
      thread.Start(i);
    }

    foreach (var thread in threads) thread.Join();
  }

  private static void DoWork(object data)
  {
    // initially set the context of the thread
    Thread.SetData(_Slot, data);

    // somewhere else, access the context again
    Console.WriteLine("Thread ID {0}: {1}", Thread.CurrentThread.ManagedThreadId, Thread.GetData(_Slot));
  }

}
Run Code Online (Sandbox Code Playgroud)

样本输出:

在此输入图像描述

这也适用于线程池产生的线程.