0

I have read a number of posts on this subject, but I'm still just a little fuzzy how C# handles parameters in methods when called from multiple threads.

I have a series of utility methods that need to be called from about 60+ threads. It's a process that downloads patient data for roughly 20,000-30,000 patients every day. For the most part, the methods look like this.


    Public Static SomeClass
    {
        public static string StringToSQLBool(string s)
        {
           if (s.Trim() == "")
           {
              return "Null";
           }
           else
           {
              if (s.ToLower() == "true")
              {
                 return "1";
              }
              {
                 return "0";
              }
           }
        }

        public static string DateToSQLAnsiStr(string ADate)
        {
            try
            {
               if (ADate.Trim() != "")
               {
                  DateTime d = Convert.ToDateTime(ADate);
                  return "{d '" + d.Year.ToString() + "-" +
                          d.Month.ToString().PadLeft(2, '0') + "-" +
                          d.Day.ToString().PadLeft(2, '0') + "'}";
               }
               else
               {
                  return "Null";
               }
            }
            catch
            {
               return "Null";
            }
        }
    }

As I understand it, as long as the parameters are used in the method that are singular to the calling thread, then it would be considered safe.

Are these thread-safe without locking?

S. Zimm
  • 21
  • 4
  • 3
    They're strings. Strings are immutable. And yes, as long as reference types passed as parameters are only accessed within that thread, then there is no need for locking, etc. It's only a problem if you pass one class instance into two separate threads and then start trying to manipulate the same variables. – ProgrammingLlama Jul 07 '17 at 14:59
  • You've only ever shown single threaded code, so we couldn't possibly comment on the safety of operations *that you haven't shown*. – Servy Jul 07 '17 at 15:19
  • Your code seems fundamentally wrong. It implies that you build up a string of individual parts to get your SQL query, something like this ``var sqlQuery = "update tableName set column1 = '" + text + "' where id = " + 1;`` This way to build your SQL Query has many issues, like SQL Injections (https://stackoverflow.com/questions/601300), you have to deal with different types of value yourself (like you are doing) and others. You should ALWAYS use parameterized queries!!! – Rand Random Jul 07 '17 at 15:20
  • @RandRandom, that's not what I'm doing. – S. Zimm Jul 07 '17 at 15:24
  • May I ask what your code is for? – Rand Random Jul 07 '17 at 15:29

3 Answers3

3

Threading is an issue when trying to manipulate (or manipulate in one and access in another) the same objects across threads. It does not matter by what 'name' the objects are accessed.

Using the term 'variable' to discuss class members is a less than ideal way, especially in context, to refer to fields. And that is the key difference here: local variables, including parameters, can never be accessed by two threads at once1.

To answer the question verbatim: "parameters are always thread-safe" although the objects that they evaluate to may not be.

However, in the example code, only immutable objects2 are used:

The String + operator returns a new string, being the concatenation of the two, and it is this new String result which is re-assigned to the local (parameter) variable. The same logic applies for the DateTime.

Thus, there is no threading issue with the posted code; because there is no shared manipulation (or manipulation and access) of the same objects, regardless of local variables or parameters.


1 Access to closure-bound variables, including parameters, must generally treated as field access in context of threading. This is because the C# compiler synthesizes/creates a hidden object behind the scenes which is then manipulated to store the closure state.

2 If an object cannot be manipulated after it is created, it is considered an immutable type and is inherently thread-safe. Strings fall into this category. (Thread-safety of immutable objects is only guaranteed after the object has been fully constructed.)

user2864740
  • 60,010
  • 15
  • 145
  • 220
3

TL;DR - According to how the question was asked, yes. Parameters are thread safe in the sense that two threads can call the same method at the same time passing different parameters.


Each call to a method from a different thread has its own stack. Value types passed to the method are stored on the stack. Pointers to reference types passed to the method are stored on the stack. Either way it's on the stack.

Because each thread has its own stack, multiple calls to a method from different threads don't "overwrite" each others' parameters.

As I understand it, as long as the parameters are used in the method that are singular to the calling thread, then it would be considered safe.

There's a tendency to pick statements like this apart like a lawyer (especially since it involves what sounds like medical records.) Your understanding is correct.

I'm not saying that it's wrong to pick questions apart like a lawyer. Details matter. But you asked your question very clearly so I get what you mean.

How do I say this without sounding somehow patronizing, because you're likely a very experienced programmer and this just happens to be your first time working with multithreading specifically using .NET. Please be careful. I'm horrified at the thought of medical records going to the wrong person, claims being denied, or someone accidentally getting chemotherapy or gender reassignment because of a threading error. I think in this case the community should be highly motivated to assist with all of your multithreading questions.

Scott Hannen
  • 27,588
  • 3
  • 45
  • 62
  • Thanks Scott. Yes I've been developing for over 30 years. But only a couple of months with C#. I've been tasked with moving a previous multi-threaded app that I wrote in another language to C#. I have found C# to be quirky and the object model design a bit funky. Probably due to MS trying to make it "easy" to use. I have written several threaded apps, just not in C#. So not worry, no ones data is going to get assigned to the wrong patient. ;) – S. Zimm Jul 10 '17 at 12:53
0

The answer to the question in your title is "maybe; it depends on their type."

  • Value types: yes
  • Reference types:
    • Immutable objects: yes
    • Normal objects: no
Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328