Question

I'm trying to shallow-copy a double[] into segments, and pass those segments to new threads, like so:

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

What would be the best way to have the created segments reference the original array?

Was it helpful?

Solution

You could use the ArraySegment<T> structure:

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

(note that you will need to change the signature of DoStuff to accept an ArraySegment<double> (or at least an IList<double> instead of an array)

ArraySegment<T> doesn't copy the data; it just represents an segment of the array, by keeping a reference to the original array, an offset and a count. Since .NET 4.5 it implements IList<T>, which means you can use it without worrying about manipulating the offset and count.

In pre-.NET 4.5, you can create an extension method to allow easy enumeration of the ArraySegment<T>:

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())
{
    ...
}

If you need to access the items by index, you will need to create a wrapper that implements IList<T>. Here's a simple implementation: http://pastebin.com/cRcpBemQ

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top