gpt4 book ai didi

c# - System.Array 的 SetValue/GetValue 方法是线程安全的吗?

转载 作者:太空狗 更新时间:2023-10-29 23:35:32 24 4
gpt4 key购买 nike

我们在办公室进行了一些讨论,但没有得到书面答复:

System.Array.SetValue 线程安全吗?

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

这没有记录。查看 MSDN 的文档 System.Array一般来说,到SetValue(object, int)特别是..与线程安全无关(或者我可能遗漏了一些东西)。

正如 Jon Skeet 对 similar question 的回答所表达的那样:

I believe that if each thread only works on a separate part of the array, all will be well

关于这个问题,我正试图对 GetValue(int)SetValue(object, int) 得到明确的答案。有人有文档链接和/或对 InternalSetValue 有更好的理解吗?

最佳答案

MSDN:Array class

Public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

This implementation does not provide a synchronized (thread safe) wrapper for an Array; however, .NET Framework classes based on Array provide their own synchronized version of the collection using the SyncRoot property.

这不是线程安全的!

编辑:

一些额外的信息,Array 类的 SetValue 方法在正常情况下不会被调用,只有在通过 IList 接口(interface)使用数组时才会被调用。

以下代码:

int[] arr = ...
arr[i] = value;

不会生成对 SetValue() 的调用,而是生成 OpCodes.Stelem 操作码。

因此,除非使用 IList 引用访问数组,否则 SetValue 方法是否线程安全是无关紧要的。

关于c# - System.Array 的 SetValue/GetValue 方法是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1874488/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com