So I have a method that gets a Dictionary of List<myObj>, then cycles through the keys of the dictionary and passes each List<myObj> to a separate thread.

Here is some Code / Psuedo-Code:

public static void ProcessEntries() {

    Dictionary<string, List<myObj>> myDictionary = GetDictionary();

    foreach(string key in myDictionary.keys)
    {

        List<myObj> myList = myDictionary[key];

        Thread myThread = new System.Threading.Thread(new System.Threading.ThreadStart(delegate() {

            ProcessList(myList);

        }    
    }
}

public static void ProcessList(List<myObj> myList) {

    // Process entries
    // read-only operations on myList

}

The problem is that during execution of ProcessList the myList parameter simply changes.

I have looped through the list before kicking of the thread, and then immediately inside the thread, and I've found the results to be different.

I have since solved the problem (I think!) by making the Dictionary variable global. Using the [ThreadStatic] property is next on the list of possible fixes.

What I really want to know is why does the myList object changes inside ProcessList() presumably when the myList object is re-assigned in ProcessEntries() ? Are these not two different Lists ? If all parameter passing is by value by default, why does the ProcessList() function not have a local copy of myList ? (does it?)

Is there a way to specify that you want to pass a parameter to a thread and not have it be altered by the parent thread or other threads during execution? (This would be similar to the [ThreadSafe] attribute for global variables)

Edited 3 Years Ago by mike_2000_17: Fixed formatting

If all parameter passing is by value by default, why does the ProcessList() function not have a local copy of myList ? (does it?)

Objects and other reference types (this includes lists) are passed by reference by default. Or rather, the object reference is passed by value (which is sort of the same thing).
This means that any changes to the list done in the // Process Entries section of ProcessList are reflected in the list referenced by the dictionary (because it is the same list).

[Edit] Instead of passing the list you could get an array of the objects using myList.ToArray() and pass that.
Changes to the list (array) will not affect the dictionary lists (and vice-versa).
Note: Any changes done to the objects (since these are also references) will still be reflected in object refereced by the dictionary lists.

Edited 6 Years Ago by nick.crane: n/a

Thanks Nick,

I hear ya, on the reference being passed by value (i.e. a reference parameter), however, there are no modifications to the Lists or to the Dictionary while the threads are running; there are only read-only operations performed on these objects.

I have looped through the list before kicking of the thread, and then immediately inside the thread, and I've found the results to be different.

What sort of differences did you find?
Does it appear to be the next or further lists from the dictionary?
I think that the myList variable is being re-assigned as you enumerate the dictionary.
Try using a ParameterizedThreadStart instead.

Thread myThread = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(ProcessList));
myThread.Start(myList);

Edited 6 Years Ago by nick.crane: n/a

This article has been dead for over six months. Start a new discussion instead.