泛型或类型对象的参数,线程安全吗?

Are parameters of generic type or type object, thread safe?

   [Webmethod]

     Public static string GetAge(List<int> input1, string input2)
     {
     Cust cu=Cust.CalAge(input1,input2)
     cu.agemodify=true;

     }

AJAX 调用调用此 Web 服务。

CalAge是class里面的静态方法Cust.

agemodify 是 class Cust.

中的 boolean 字段
  1. 我了解所有非静态 fields/local 变量都有 即使在静态方法中,每个线程在堆栈上也有不同的副本。是 那对吗?所以这些是线程安全的,不是共享资源。 因此 agemodify 是线程安全的吗?
  2. 我的理解是List<int>作为参数是线程安全的 到静态方法,因为对于 int,不可变性不适用。是 那对吗?我知道 list <T> 不是线程安全的。只是 <T>s 作为参数,如果 T 是不可变的,或者是对象,如果它们是 不变的?例如public static int GenMethod<TFirst,TSecond>(), GetMethod(List<object> o1, object o2). 只是对象 vs List<Object>. 我不想使用 System.Collections.Concurrent。
  3. 我的理解是,因为 Webmethod 是静态的,任何 classes 不需要实例化堆栈的更下方,因此, 也可能是静态的,因为只有一个 Webmethod "instance" 自始至终。那是对的吗?有一个更好吗 专用网络服务 (wcf/asmx) wrt 线程安全而不是静态 aspx 页面上的 web 方法?

不幸的是,您的问题过于宽泛。您似乎将几个不同且完全不相关的概念混为一谈,就好像它们以某种有意义的方式相互关联,即使它们之间没有关联。我怀疑在 Stack Overflow 答案的上下文中,是否有可能解开此处表示的所有误解。

话虽如此,我会试试的。至少,我希望通过以下内容,有足够的信息可以让您返回查看主要来源(例如 MSDN、其他文档)并纠正您的理解。在最好的情况下,也许下面的内容足以让您完全回到正轨。

  1. I understand that all non static fields/local variables have different copies on the stack per thread even in a static method. Is that correct? So these are thread safe and are not shared resources. agemodify is therefore thread safe?

"Is that correct?" — 不,这是边缘的胡言乱语。在方法中声明的局部变量有一个新实例,因此在方法中传递或初始化的任何值都有一个新副本,每次调用方法。所以,是的,在局部变量的情况下,每次在不同线程中调用该方法时,都会有新的副本,但这与线程无关。都是关于方法调用的。

至于 non-static 字段,它们可能存储在堆栈中,也可能不存储在堆栈中†,因此任何基于假设它们存储在堆栈中的结论都必然是错误的。对于引用类型,您只能为对象的每个实例获取一个新副本。对于值类型,您也会为值类型的每个实例获得每个字段的新副本,但是由于每次将值类型分配给新变量时您都会获得一个值类型的新实例,因此可以有更多副本。但同样,与线程无关,与堆栈无关(因为值类型可以存在于堆上的堆栈上)。

"agemodify is therefore thread safe?" — 没有足够的代码来回答这个问题。您需要为任何人提供一个好的 Minimal, Complete, and Verifiable code example 来明确回答。如果 Cust 类型是引用类型, CalAge() 方法总是创建该类型的新实例,或者 Cust 类型是一个值类型,那么我会说是的,该字段是线程安全的。

否则,不一定。

† 就此而言,局部变量存储在堆栈中只是一个实现细节。它不太可能改变常规局部变量,但在 C# 中没有要求以这种方式处理它们。它们可以存储在任何地方,只要编译器保留局部变量的语义,实际上这正是 C# 中各种上下文中发生的情况,例如捕获的局部变量,以及在迭代器方法等特殊方法中找到的局部变量和 async 方法。

  1. My understanding is that List<int> is thread safe as a parameter to a static method because for int immutability doesn't apply. Is that correct? I know List<T> isn't threadsafe. What about just <T>s as parameters if T is immutable or Objects if they are immutable? e.g. public static int GenMethod<TFirst,TSecond>(), GetMethod(List<object> o1, object o2). Just Object vs List<Object>. I don't want to use System.Collections.Concurrent.

同样,所有这些大多没有任何意义。 input1 变量的值是一个局部变量,本质上是线程安全的,因为每次调用该方法都存在一个新副本。但这只是变数。 List<int> 对象本身完全不受此影响,并且肯定是 而不是 thread-safe。仅当执行该方法的每个线程都获得 List<int> 对象的唯一实例时,您才能说那将是 thread-safe.

至于类型参数的值 T 去,泛型没有任何东西可以使这些固有 thread-safe。就thread-safety而言,T只是另一种类型。在编译泛型类型或方法时您不知道类型这一事实是无关紧要的,并且不会以任何方式帮助生成该类型的值 thread-safe.

  1. My understanding is that because Webmethod is static, any classes further down the stack need not be instantiated, and therefore, might as well be static because there will only be one Webmethod "instance" throughout. Is that correct? Is it better to have a dedicated webservice (wcf/asmx) wrt thread safety instead of static webmethods on an aspx page?

抱歉,更多的是无意义的单词组合。 "classes further down the stack"是什么意思?例如,如果你调用一个需要使用 string 值的方法,你真的认为这意味着你可以使用一些神秘的 static 版本的 string 类型,只是因为调用方是静态的?

不,关于什么是 static 什么不是的规则与来电者没有太大关系。调用者唯一影响的是 non-static 调用者无需提供显式实例引用即可在同一 class[=75] 中使用其他 non-static 成员 =],因为在那个上下文中有一个隐式的 this 引用。否则,调用实例成员的 static 方法仍然需要实例引用。如果您可以使 static 方法使用的成员也成为 static,那就更好了,因为那样您就不必提供该实例了。

但仅仅因为调用者本身是 static,这并不 自动 意味着您可以避免在调用上下文中实例化对象。如果您需要访问某种类型的实例成员,您仍然需要该类型的实例。

就网络 service-specific 内容而言,这完全取决于您的方法中使用的值的性质。您的问题中没有足够的上下文来提供有关该问题的任何形式的明确讨论。