4

double []をセグメントに浅くコピーし、次のようにそれらのセグメントを新しいスレッドに渡そうとしています。

for (int i = 0; i < threadsArray.Length; i++)
{
    sub[i] = new double[4];

    //Doesn't shallow copy since double is a value type
    Array.Copy(full, i * 4, sub[i], 0, 4);
    double[] tempSub = sub[i];

    threadsArray[i] = new Thread(() => DoStuff(tempSub));
    threadsArray[i].Start();               
}

作成されたセグメントに元の配列を参照させるための最良の方法は何でしょうか?

4

1 に答える 1

2

ArraySegment<T>次の構造を使用できます。

for (int i = 0; i < threadsArray.Length; i++)
{
    sub[i] = new ArraySegment<double>(full, i * 4, 4);

    ArraySegment<double> tempSub = sub[i];

    threadsArray[i] = new Thread(() => DoStuff(tempSub));
    threadsArray[i].Start(); 
}

( (または少なくとも配列の代わりに)DoStuffを受け入れるには、の署名を変更する必要があることに注意してくださいArraySegment<double>IList<double>

ArraySegment<T>データをコピーしません。元の配列への参照、オフセット、およびカウントを保持することにより、配列のセグメントを表すだけです。.NET 4.5以降はIList<T>、を実装しています。つまり、オフセットとカウントの操作を気にせずに使用できます。

ArraySegment<T>.NET 4.5より前では、拡張メソッドを作成して、 :を簡単に列挙できるようにすることができます。

public static IEnumerable<T> AsEnumerable<T>(this ArraySegment<T> segment)
{
    for (int i = 0; i < segment.Count; i++)
    {
        yield return segment.Array[segment.Offset + i];
    }
}

...

ArraySegment<double> segment = ...
foreach (double d in segment.AsEnumerable())
{
    ...
}

インデックスでアイテムにアクセスする必要がある場合は、を実装するラッパーを作成する必要がありますIList<T>。簡単な実装は次のとおりです:http://pastebin.com/cRcpBemQ

于 2012-10-12T19:15:35.567 に答える