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スレッドが設定した後に変更されたかどうかをテストするようにコードを変更しましたが、時々変更されることわかりました。

次のコードは "Error!" を出力します。変更された場合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 に答える