通过多线程调用静态方法 - 它们可以干扰彼此的输入参数吗

Mri*_*boj 3 c# multithreading static-methods task-parallel-library parallel.foreach

我的代码被 AJAX UI(多线程)调用,并在数据处理后发送 Json 输出。最近在重构代码时,我们将许多常见和重复的方法转移到一个单独的文件中,在那里我们将它们设为静态,因为我们没有处理任何静态/共享数据。以下是我们静态方法的示例设计:

public class Helper
{
   public static C Method1(List<A> aList, List<B> bList)
   {
      C objC = new C();

      // Create ObjC based on inputs aList and bList

      return objC;
   }
}
Run Code Online (Sandbox Code Playgroud)

现在,我的理解是以下调用不会有问题,在 Parallel.foreach 或任何其他多线程场景中调用时,请验证。

C resultC = Helper.Method1(aList, bList);
Run Code Online (Sandbox Code Playgroud)

但是我们怀疑,是否有一种罕见的情况可能是两个线程进行上述调用并且aList,bList的一个线程数据被另一个线程替换,从而给出有缺陷的结果(可能是异常),这可以为问题将无法调试和重复,因为两个线程必须在精确的毫秒内同时执行/执行该方法所需的时间

请分享您的观点,我们是否在正确的轨道上创建上述设计,或者有我们无法看到的坑。我们可以很容易地通过实例方法替换,在这种情况下它们肯定是线程安全的,因为每个线程都有自己的实例可以使用,但是我觉得可能不需要并且继续创建实例很麻烦,当我们可以方便地使用时静态调用。

请注意,到目前为止我还没有看到代码运行出现问题,但正如我所说,如果发生这种情况,这将是极端情况,两个线程同时出现,一个线程替换输入参数,而另一个线程仍在处理结果。

Ian*_*Ian 5

您的问题的简短答案是否定的,只要您List在所有不同的线程中传递不同的实例。.NET处理线程很好,并且本身不会陷入困境,只有当您的代码鼓励它这样做时,事情才会变得混乱。

事情变得混乱的方式是在不同的线程之间共享状态。举个例子,有一个静态方法,你可能认为在某处使用静态变量是个好主意:

private static int count;

public static void MyMethod() {
   count = count + 1;
   if(count == 5) {
      console.log("Equal to 5");
   }
};
Run Code Online (Sandbox Code Playgroud)

这种方法不是线程安全的,因为count可以同时被两个不同的线程修改。事实上,它可能count会增加到 5,然后另一个线程在if检查之前将它增加到 6 ,因此你永远不会记录任何东西 - 这显然会有点混乱。

您可以共享状态的另一种方式是,如果您传入某些内容,因此我在答案开头提出警告。如果您将同一个对象从多个线程传递到方法中,则该对象理想情况下应该是不可变的,因此在您的情况下是一个无法修改的集合。这可以防止方法的内部修改可能影响另一个线程的对象。正如已经提到的,如果您在不同的线程中传入相同的实例,这只是一个问题。