2

这不完全是我对代码所做的,但它应该代表交换数组引用的场景。我不确定数组的类型是否重要,但我仍然在标题中指定了它。

  1. 在循环之外声明一些 DataRow 数组。将它们命名为 Array1、Array2 ... ArrayX 等
  2. Array1 = Array2 或 Array1 = Array3 ... 或 Array1 = ArrayX 取决于迭代变量
  3. 用 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:这是我在这里的第一个问题,所以我希望我没有犯任何错误:p 在尝试将其发布在这里之前,我确实阅读了其他一些问题,但他们并没有真正回答我的问题...

4

1 回答 1

0

我认为你错了,有问题

我修改了您的代码以测试是否Array1在线程设置后更改,结果发现它有时会更改。

以下代码将打印“错误!” 如果Array1改变了。在我的系统上,它在发布或调试版本(四核处理器)上多次打印“错误”。

每次运行的结果都不同(您对竞态条件的期望):

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!");
                }
             });
         }
    }
}
于 2013-04-06T09:00:51.970 回答