Search code examples
c#multithreadingtask-parallel-librarystatic-methodsparallel.foreach

Calling static method via Multiple threads - Can they meddle with each other's Input Parameters


My code gets called by AJAX UI (Multiple threads), and post data processing it sends output in Json. Recently while refactoring the code, we have shifted lot of common and repeated methods to a separate file, where we have made the them static, since we are not working on any static / shared data. Following is a sample design our static method:

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;
   }
}

Now, my understanding is that the following call will have no issue, when called in a Parallel.foreach or any other multithread scenario, please verify.

C resultC = Helper.Method1(aList, bList);

However we have doubt, can there be a rare case possible where two threads make the above mentioned call and one thread data of aList, bList, is replaced by another thread, thus giving a flawed result (may be exception), which can for that matter will be impossible to debug and repeat, since two threads have to go / execute together in precise milli seconds that method takes to execute

Please share your view are we on right track to create the above mentioned design or there are pits that we are not able to see. We can easily replace by instance method, they are surely thread safe in this scenario, since each thread has its own instance to work with, but I feel that may not be required and its troublesome to keep creating instance, when we can conveniently work with a static call.

Please note till now I haven't seen an issue with code running, but as I said if this ever happens it will be corner case, for two threads to come at same time and one thread replace the input parameter while other thread is still processing result.


Solution

  • The short answer to your question is no, as long as you pass in different List instances across all your different threads. .NET handles threading fine, and in itself won't get itself into a tangle, it's only if your code encourages it to do so can things get messy.

    The way things get mixed up is by sharing state across different threads. So as an example, having a static method you may think it a good idea to use a static variable somewhere:

    private static int count;
    
    public static void MyMethod() {
       count = count + 1;
       if(count == 5) {
          console.log("Equal to 5");
       }
    };
    

    This sort of method is not thread safe because count can be modified by two different threads at the same time. In fact it's possible that count could be incremented to 5, and then another thread increment it to 6 before the if check, therefore you'd never log anything - which would obviously be a bit confusing.

    The other way you can share state, is if you pass something in, hence my caveat at the start of the answer. If you pass the same object into the method from multiple threads this object should ideally be immutable so in your case a collection that can't be modified. This prevents the internals of the method modifying the object that could impact another thread. As already mentioned though, this is only a concern if you pass the same instances in, within different threads.