【问题标题】:ThreadStatic variables vs instantializationThreadStatic 变量与实例化
【发布时间】:2018-04-19 21:19:09
【问题描述】:

如果您在静态字段上设置 ThreadStatic 标志,则运行的每个线程都会有一个单独的变量,因此如果您有一个 static int 字段和一个仅将其值递增 5 次的方法,则在两次启动该方法单独的线程只会给你两个独立的值为 5 的整数,而不是一个值为 10 的整数。

在这种情况下,这种方法与为每个线程实例化的非静态字段有什么区别?

【问题讨论】:

  • 您的函数不一定要由线程运行。假设您的 Function 将始终/永远不会从多个线程中调用是一个坏主意。这样,它就可以适应现实。
  • @Christopher: Everything 在线程上执行。不清楚您所说的“您的函数不一定要由线程运行”是什么意思
  • @DaisyShipton:除非您是创建线程的人,否则您如何确定线程具有本地副本?
  • @Christopher:“本地副本”是什么意思? [ThreadStatic] 的要点是它实际上每个线程都有一个独立变量。我真的不清楚你在这里想说什么。
  • @DaisyShipton:据我了解,问题是关于“线程静态”与“每个线程有一个单独的变量”。我也是这么回答的。

标签: c# multithreading static


【解决方案1】:

ThreadStaticAttribute 装饰有:

[AttributeUsageAttribute(AttributeTargets.Field, Inherited = false)]

所以你不能将它应用于方法,只能应用于字段。每个线程实际上都有一个对应于该字段的自变量。但它只能应用于静态字段 - 您不能拥有“每个实例和每个线程”字段,而这正是您所要求的。

现在是的,如果您对运行代码的线程有足够的控制,那么您就可以为每个线程创建一个单独的对象,并使用一个实例字段,那么是的,这是一个非常好的选择到ThreadStatic。但是,情况并非总是如此。有时您需要编写可以安全地从多个线程调用的代码,但不能很好地将每个线程划分为单独的对象。 ThreadStatic 对此很有用。

话虽如此,我通常会使用ThreadLocal<T> 而不是ThreadStatic 作为获得每个线程数据的替代方法。

附带说明,您不能在方法中拥有静态变量。您只能在方法中声明 local 变量,它们既不是静态字段也不是实例字段——它们只是局部变量。您可以拥有一个仅在单个方法中使用的静态字段,但这与在方法中声明变量不同。

【讨论】:

  • 哦,是的,我的错误,我措辞不好。我会尝试编辑我的问题。
  • 作为一般规则,您应该始终避免使用静态方法。分配给静态变量的实例大约是我最接近它的实例。在“要避免的事情”列表中,静态是在赤裸裸的 goto 周围的某个地方。与那个一样,你不能总是这样做。但如果你无法避免,通常是因为其他人在他可以避免的时候没有避免。
  • @Christopher 为什么呢?我在一个简单的应用程序中使用了静态方法和变量,我总是希望它们只有一个实例,这使它变得非常容易,而且在这种情况下它不是静态的只会增加不必要的复杂性。
  • @J.Doe:静态是全局状态。这使得推理变得更加困难,并且随着程序变得更大,问题变得更糟。这也使得测试变得更加困难。
  • @J.Doe: 任何不得不用非静态类替换 Windows SettingsManager (msdn.microsoft.com/en-us/library/…) 或用新类替换 Databse Access 类的人(因为后端数据库已更改) ) 可以详细解释为什么静态方法是 PITA。将静态变为非静态或用另一个静态类替换一个静态类需要在代码中的每次使用时更改字面意思。如果你走的是实例路线,它正在改变初始化步骤。这甚至可以在运行时完成。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-21
  • 2014-10-18
  • 2014-10-05
  • 1970-01-01
  • 2015-04-26
  • 2013-03-24
  • 1970-01-01
相关资源
最近更新 更多