Подтвердить что ты не робот

Установка глобальной переменной в потоке - С#

У меня есть HTTP-сервер, который я пишу, используя HTTP-прослушиватель, и я хотел бы как-то объявить определенные переменные доступными из любого места в потоке.

  • Мой класс webserver основан на базе instanced, поэтому я не могу использовать статическую переменную.
  • Я мог бы использовать переменную экземпляра, поскольку весь код находится в одном классе, но... я не знаю.

Я думал о использовании словаря: Dictionary</*[type of Thread ID here]*/,ThreadData>, но я думаю, что могут возникнуть проблемы с потоками. ThreadData, вероятно, будет экземпляром класса, но я мог бы использовать struct, в зависимости от того, что было бы более эффективным.

  • Если бы я ввел словарь в ИД потоков и запрограммировал его так, чтобы один поток запрашивал только свою собственную запись в словаре, были ли какие-либо связанные с потоком проблемы при доступе к словарю?
  • Каждый поток добавит свою собственную запись. Должен ли я заблокировать словарь, пока я добавляю новые элементы потока? Если да, смогу ли я использовать отдельный объект блокировки, чтобы позволить потокам получать доступ к своим собственным данным за это время?

Будет ли преимущество использования параллельного словаря? Есть ли другой способ, который более безопасен для потоков?

В настоящее время я использую ThreadPool.QueueUserWorkItem. Я точно не знаю, что для каждого элемента используется новый поток. Если нет, то я мог бы также указать его в контексте.

Обновление: Согласно ThreadPool class - MSDN, он повторно использует потоки. И он не очищает данные потоков.

Когда пул потоков повторно использует поток, он не очищает данные в локальном хранилище потоков или в полях, отмеченных атрибутом ThreadStaticAttribute. Поэтому, когда метод проверяет локальное хранилище потоков или поля, помеченные атрибутом ThreadStaticAttribute, найденные значения могут быть оставлены из более раннего использования потока потока потока.

4b9b3361

Ответ 1

Одним из решений было бы использовать публичное статическое поле, с атрибутом ThreadStatic:

[ThreadStatic]
public static int ThreadSpecificStaticValue;

Статическое поле, помеченное символом ThreadStaticAttribute, не разделяется между потоки. Каждый исполняемый поток имеет отдельный экземпляр поля, и независимо устанавливает и получает значения для этого поля. Если поле доступ к нему в другом потоке, он будет содержать другое значение.

Ответ 2

Вы можете использовать встроенный механизм хранения класса потока:

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));
  }

}

Пример вывода:

enter image description here

Это будет работать с потоками, порожденными пулом потоков.

Ответ 3

Если ваш веб-сервер основан на экземпляре, почему бы не сохранить все необходимые данные? Если каждый экземпляр заблокирован для определенного потока, проблем не должно быть.

Ответ 4

Почему вы хотите создать HTTP-сервер, используйте SignalR, выглядит странно, но подумайте об этом