We had a little discussion in the office, and got no documented answer:
Is System.Array.SetValue thread safe?
using System;
using System.Text;
using System.Threading;
namespace MyApp
{
    class Program
    {
        private static readonly object[] arr = new object[3];
        static void Main(string[] args)
        {
            string value1 = "hello";
            int value2 = 123;
            StringBuilder value3 = new StringBuilder();
            value3.Append("this"); 
            value3.Append(" is "); 
            value3.Append("from the StringBuilder");
            var states = new object[]
                             {
                                 new object[] {0, value1},
                                 new object[] {1, value2},
                                 new object[] {2, value3}
                             };
            ThreadPool.QueueUserWorkItem(MySetValue, states[0]);
            ThreadPool.QueueUserWorkItem(MySetValue, states[1]);
            ThreadPool.QueueUserWorkItem(MySetValue, states[2]);
            Thread.Sleep(0);
            Console.WriteLine("press enter to continue");
            Console.ReadLine();
            // print the result
            Console.WriteLine("result:");
            for (int i = 0; i < arr.Length; i++)
            {
                Console.WriteLine("arr[{0}] = {1}", i, arr[i]);
            }
            // quit
            Console.WriteLine("press enter to quit");
            Console.ReadLine();
        }
        // callback
        private static void MySetValue(object state)
        {
            var args = (object[]) state;
            var index = (int)args[0];
            var value = args[1];
            arr[index] = value; // THREAD-SAFE ??
        }
    }
}
As you can see, every thread sets a different, unique item in the static array. I looked deep into the code using reflector (and looked into mscorlib.pdb). Eventually there's a call to:
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private unsafe extern static void InternalSetValue(void * target, Object value);
Which is not documented. Take a look at MSDN's documentation to System.Array in general, and to SetValue(object, int) in particular.. Nothing about thread-safety (or maybe I'm missing something).
As it's expressed by Jon Skeet's answer to a similar question:
I believe that if each thread only works on a separate part of the array, all will be well
I'm trying to get a definite answer to GetValue(int) and SetValue(object, int) regarding this issue. Does someone have a documentation link and/or a better understanding of InternalSetValue?