TL; DR
Если вы не хотите, чтобы переменная повторно использовалась несколькими потоками в многопоточном приложении, нет причин делать ее статичной.
Если мы не хотимпеременная, повторно используемая тем же потоком, сомнительно, почему мы намеренно использовали [ThreadStatic]
, поскольку это то, что она позволяет нам делать.
Я сосредоточен на аспекте ThreadStatic
этого, посколькукажется, что он находится в центре внимания вопроса.
, поэтому любое последующее использование определенного потока получает новую копию переменной.
Использование потока don 'Не требуется собственная копия переменной. Методы , использующие переменную , могут нуждаться или не нуждаться в собственной копии переменной.Это звучит как потрясающая вещь, но поток сам по себе не нуждается в копии какой-либо переменной.Это может делать вещи, не связанные с этим статическим классом и этой переменной.
Когда мы используем переменную, мы заботимся, является ли она "свежей копией".То есть, когда мы вызываем метод, который использует переменную.
Если, когда мы используем статическую переменную (которая объявлена вне метода), мы хотим убедиться, что она была создана заново, прежде чем мы используемэто и распоряжаться, когда мы закончили с этим, тогда мы можем сделать это в рамках метода, который его использует.Мы можем создать его, утилизировать или даже установить на null
, если захотим.Однако, когда мы делаем это, становится очевидным, что это обычно исключает необходимость объявления переменной вне метода, который ее использует.
Если мы делаем это:
public static class HasDisposableThreadStaticThing
{
[ThreadStatic]
public static DisposableThing Foo;
public static void UseDisposableThing()
{
try
{
using (Foo = new DisposableThing())
{
Foo.DoSomething();
}
}
finally
{
Foo = null;
}
}
}
Мы достигли цели.
Можно ли каким-либо образом сбросить переменную ThreadStatic к значению по умолчанию или к нулю при повторном использовании потока?
Готово.Каждый раз, когда один и тот же поток входит в метод («поток используется повторно»), он становится нулевым.
Но если это то, что мы хотим, то почему бы просто не сделать это?
public static class HasDisposableThreadStaticThing
{
public static void UseDisposableThing()
{
using (var foo = new DisposableThing())
{
foo.DoSomething();
}
}
}
Результат точно такой же.Каждый поток начинается с нового экземпляра DisposableThing
, потому что когда он выполняет метод, он объявляет переменную и создает новый экземпляр.Вместо установки null
ссылка выходит из области видимости.
Единственное различие между ними состоит в том, что в первом примере DisposableThing
открыто выставляется вне класса.Это означает, что другие потоки могут использовать его вместо объявления своей собственной переменной, что странно.Поскольку им также необходимо убедиться, что он создан, прежде чем его использовать, почему бы им просто не создать свой собственный экземпляр, как во втором примере?
Самый простой и нормальный способ обеспечить инициализацию переменнойи каждый раз, когда это необходимо в статическом методе, он объявляет эту переменную локально в статическом методе и создает новый экземпляр.Затем независимо от того, сколько потоков вызывает его одновременно, каждый из них будет использовать отдельный экземпляр.