После каждого Enqueue () все значения в очереди становятся одинаковыми

1

Я получаю некоторые данные через сокет и пытаюсь добавить его в очередь, поэтому его можно удалить из другого потока, который намного медленнее, что-то вроде буфера.

Проблема в том, что каждый раз, когда я вставляю новое значение, все значения в очереди становятся таковыми.

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

Но у меня такая же проблема.

Любая идеа, как это осуществить?

Теги:
pointers
queue

2 ответа

2
Лучший ответ

Вот что происходит (см. Комментарии):

// 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 в новый массив байтов, удостоверяясь, что все экземпляры, которые вы вставляете в очередь, независимы

  • 0
    Спасибо, это сработало. Просто помогите мне разобраться, когда я сделал (byte[])(ar.AsyncState) он фактически получил указатель на AsyncState, так что я должен явным образом преобразовать его в массив, чтобы получить данные?
  • 0
    @FvZ Приведения (то есть части (byte[]) ) достаточно для преобразования объекта в массив. ToArray() создает копию массива, даже если у вас уже есть массив. Массив внутри ar.AsyncState копируется в новый массив.
Показать ещё 1 комментарий
0

Вы передаете ссылку. Когда вы назначаете массив другому, это копия, которая не копирует данные в массиве.

Чтобы сделать копию массива, вам нужно специально скопировать данные внутри него. Пример:

// 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);

Ещё вопросы

Сообщество Overcoder
Наверх
Меню