우리는 사무실에서 약간의 토론을 가졌으며 문서화 된 답변을 얻지 못했습니다. 은 안전합니까?System.Array의 SetValue/GetValue 메서드는 스레드로부터 안전합니까?
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 ??
}
}
}
모든 스레드는 정적 배열에서 다른 고유 항목을 설정합니다. 리플렉터를 사용하여 코드를 자세히 살펴 보았고 mscorlib.pdb를 살펴 보았습니다. 결국
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private unsafe extern static void InternalSetValue(void * target, Object value);
에 대한 전화가 있습니다. 일반적으로 System.Array
및 특히 SetValue(object, int)
에 대한 MSDN의 설명서를 살펴보십시오. 스레드 안전성에 관한 내용은 없습니다.
그것은에 존 소총의 대답에 의해 표현 된 것 같이 similar question :
내가 배열의 별도 부분에 각 스레드는 일 경우, 모두가 잘
I 될 것이라고 믿는다 이 문제와 관련하여 GetValue(int)
및 SetValue(object, int)
에 대한 확실한 답변을 얻으려고합니다. 다른 사람이 문서 링크가 있거나 InternalSetValue
을 더 잘 이해하고 있습니까?
에릭 리 퍼트 (Eric Lippert)가 실제로 의미하는 "스레드 안전성"에 대한 유용한 정보 : http://blogs.msdn.com/ericlippert/archive/2009/10/19/what-is-this-thing-you-call -thread-safe.aspx –
예제에서 SetValue 메서드는 호출되지 않고 컴파일러에서 Stelem opcode가 생성되고 호출 opcode는 출력되지 않습니다. –