Я получаю некоторые данные через сокет и пытаюсь добавить его в очередь, поэтому его можно удалить из другого потока, который намного медленнее, что-то вроде буфера.
Проблема в том, что каждый раз, когда я вставляю новое значение, все значения в очереди становятся таковыми.
byte[] aux = new byte[1464];
aux = (byte[])ar.AsyncState;
//add the package to the package fifo list
lock (lockPktBuffer)
{
packetBuffer.Enqueue(aux);
}
Сначала я думал, что передаю указатель, так что все записи просто указывают на одну и ту же переменную.
Поэтому я попытался сделать это:
lock (lockPktBuffer)
{
packetBuffer.Enqueue((byte[])ar.AsyncState);
}
Но у меня такая же проблема.
Любая идеа, как это осуществить?
Вот что происходит (см. Комментарии):
// This line creates a new array
byte[] aux = new byte[1464];
// This line "forgets" the new array, and replaces it with ar.AsyncState:
aux = (byte[])ar.AsyncState;
В результате все добавления к очереди состоят в том, чтобы вставить один и тот же объект, возвращенный из ar.AsyncState
, создавая эффект, который вы видите (все экземпляры очереди выглядят одинаково).
Вот как вы можете это исправить:
byte[] aux = ((byte[])(ar.AsyncState).ToArray();
...
packetBuffer.Enqueue(aux);
Этот вызов делает копию ar.AsyncState
в новый массив байтов, удостоверяясь, что все экземпляры, которые вы вставляете в очередь, независимы
Вы передаете ссылку. Когда вы назначаете массив другому, это копия, которая не копирует данные в массиве.
Чтобы сделать копию массива, вам нужно специально скопировать данные внутри него. Пример:
// get the reference to the source array
byte[] source = (byte[])ar.AsyncState;
// create a new array with the same size
byte[] aux = new byte[source.Length];
// copy all the values from the source
Array.Copy(source, aux, source.Length);
(byte[])(ar.AsyncState)
он фактически получил указатель на AsyncState, так что я должен явным образом преобразовать его в массив, чтобы получить данные?(byte[])
) достаточно для преобразования объекта в массив.ToArray()
создает копию массива, даже если у вас уже есть массив. Массив внутриar.AsyncState
копируется в новый массив.