c#并行修改DataRow数组引用.为什么代码可以正确运行
本文关键字:运行 代码 为什么 修改 并行 DataRow 数组 引用 | 更新日期: 2023-09-27 18:07:36
这不是我对代码所做的,但它应该代表交换数组引用的场景。我不确定数组的类型是否重要,但我仍然在标题中指定了它。
- 在循环外声明一些DataRow数组。命名为Array1, Array2…ArrayX等
- Array1 = Array2或Array1 = Array3…或Array1 = ArrayX取决于迭代变量
- 对Array1做点什么
代码应该像这样:
void Somefunction()
{
int indices[];
for (int i = 0; i < threadamount; ++i)
{
indices[i] = i;
}
DataRow[] Array1, Array2, Array3;
//assign something to these arrays
//...
//end of assigning stuff
Parallel.ForEach<int>(indices, index =>
{
if(index == 2)
Array1 = Array2;
else if(index == 3)
Array1 = Array3;
//do stuff with Array1
});
}
回到问题上来。似乎代码在所有数组上运行(在其他线程中正确地将Array2/Array3分配给Array1),没有竞争条件。
为什么?我以为我必须在循环中创建一个新变量,但是没有。是因为它实际上为每个线程创建了一个Array1引用的副本吗?每个线程中的引用Array1实际上是不同的对象?
PS:这是我的第一个问题,所以我希望我没有犯任何错误在我把这个贴出来之前,我确实读了一些其他的问题,但他们并没有真正回答我的问题。
我想你错了,有问题。
我修改了你的代码,以测试Array1
是否在线程设置后发生了变化,结果发现它是有时会发生变化。
如果更改了Array1
,下面的代码将打印"Error!"在我的系统上,它在发布或调试版本(四核处理器)上多次打印"Error"。
每次运行的结果是不同的(这是您对竞争条件的期望):
using System;
using System.Threading.Tasks;
namespace Demo
{
static class Program
{
static void Main()
{
Somefunction();
}
static void Somefunction()
{
int threadamount = 100;
int[] indices = new int[threadamount];
for (int i = 0; i < threadamount; ++i)
{
indices[i] = i;
}
int[] Array1 = new int[1],
Array2 = new int[2],
Array3 = new int[3];
Parallel.ForEach<int>(indices, index =>
{
if (index == 2)
Array1 = Array2;
else if (index == 3)
Array1 = Array3;
int[] test = Array1;
Console.WriteLine(Array1.Length);
if (!ReferenceEquals(test, Array1))
{
Console.WriteLine("Error!");
}
});
}
}
}