Локальное Хранилище Потоков Для Библиотеки Классов C#
У меня есть очень старая, но очень большая библиотека, которую я рассматриваю возможность преобразования в библиотеку классов C#. Существующая библиотека использует множество глобальных переменных, хранящихся в TLS. C# не имеет реальной концепции глобальных переменных, но один обходной путь-использовать статический класс, называемый чем-то вроде GlobalVar, и поместить их все в этот класс, чтобы к ним можно было получить доступ через GlobalVar.xxxxxx
однако я думаю, что это нарушит весь существующий код, который преобразуется как Класс GlobalVar будет обычным глобальным классом, а не хранилищем потоков. Есть ли способ заставить эти глобалы быть в потоке? т. е. Что такое эквивалент _ _ declspec (thread) static в C#?
Я должен добавить, что я ненавижу глобальные переменные. Я думаю, что они часто являются результатом плохого дизайна. Однако из-за жестких ограничений по времени Фаза 1 должна преобразовать библиотеку в C# с минимальной суетой, а затем фаза 2 будет правильно их перепроектировать.
3 ответов
есть ThreadLocal класса (введен в 4.0) и ThreadStaticAttribute.
на ThreadStaticAttribute
можно использовать только на static
поля. The ThreadLocal
класс можно использовать в "нормальных" полях, но он медленнее.
имейте в виду, что если вы не контролируете поток, в котором находитесь (например, вы являетесь страницей ASP.NET и вы начинаете с" случайного "предварительно используемого потока, или вы являетесь потоком ThreadPool), затем ваш" поток-статический " (в общем, не атрибут) переменные будут инициализированы со старыми значениями предыдущего потока. (см., например,рассказ о двух техниках: [ThreadStatic] атрибут и система.Сеть.Свойство HttpContext.Текущий.Предметы)
Я забыл, есть нить.AllocateDataSlot это имеет аналогичные "цели", чем другие.
вы можете достичь того же локального хранилища потоков, используя [ThreadStatic]
атрибут или в .Net 4 с помощью ThreadLocal
класса.
[ThreadStatic]
private static string MyThreadGlobal;
private ThreadLocal<string> MyThreadGlobal = new ThreadLocal<string>();
есть еще CallContext class но другие подходы, вероятно, предпочтительнее.
предполагая, что вы собираетесь использовать .NET 4.0, у вас может быть static ThreadLocal<ThreadLocalData>
где ваш ThreadLocalData
класс имеет все ваши переменные как свойства:
class ThreadLocalData
{
public int GlobalInt { get; set; }
public string GlobalString { get; set; }
}
class Global
{
static ThreadLocal<ThreadLocalData> _ThreadLocal =
new ThreadLocal<ThreadLocalData>( () => new ThreadLocalData() );
public static ThreadLocalData ThreadLocal
{
get { return _ThreadLocal.Value; }
}
}
затем вы получите доступ к таким свойствам:
int i = Global.ThreadLocal.GlobalInt;
вы можете добавить любые глобальные переменные, которые не являются локальными потоками, как обычные свойства Global
класса.