Структурировать в его представление ReadOnlyMemory <byte>

2

У меня есть следующая структура:

[StructLayout(LayoutKind.Sequential)]
struct Message
{
     int Header;
     int Data;
}

и я хочу отправить его по SendAsync(ReadOnlyMemory<byte>) без выделения (используя SendAsync(ReadOnlyMemory<byte>)).

Как я могу получить Memory<byte> из заданной структуры?

Я закончил с Span<byte>, а затем застрял.

var message = new Message {
  Header = 1, Data = 3
};
var bytes = MemoryMarshal.AsBytes(
    MemoryMarshal.CreateReadOnlySpan(ref message, 1)
);

Есть ли способ, как передать структуру непосредственно в поток без каких-либо распределений?

Я нахожусь в netcoreapp2.1.

  • 0
    Пролеты могут жить только в стеке. Асинхронному методу нужен его параметр, чтобы жить как минимум столько же, сколько и сама задача. Следовательно, как вы можете гарантировать, что промежуток доживает до конца задачи? Вы не можете, поэтому, почему эти методы используют память <T>, которая может жить дольше. Что означает, что вам все равно придется скопировать его.
  • 0
    @EtiennedeMartel мое message все равно перехватывается в AsyncStateMachine - это не ref struct .
Показать ещё 1 комментарий
Теги:
.net-core

1 ответ

0

Что-то вроде:

Span<Message> valSpan = stackalloc Message[1];
valSpan[0] = new Message { Header = 123, Data = 456 };
Span<byte> bytes = MemoryMarshal.Cast<Message, byte>(valSpan); // has length 8

Примечание. Я использую Span<T> здесь. В случае необходимости вы можете использовать в основном те же самые файлы с Memory<T>, но вам нужен массив поддержки или аналогичный, для которого обычно требуется выделение - если не массива, а затем пользовательского MemoryManager<T>:

var arr = new Message[1];
arr[0] = new Message { Header = 123, Data = 456 };
Memory<byte> bytes = MemoryMarshal.Cast<Message, byte>(arr); // has length 8

По сути, вы здесь очень близки:

MemoryMarshal.CreateReadOnlySpan(ref message, 1)

Однако трюк заключается в использовании MemoryMarshal.Cast<TFrom, byte>(...) чтобы получить длину байтов.

  • 0
    Хорошо, но есть ли способ сделать то же самое, если Message содержит поле, похожее на ссылку или указатель? скажем, byte[] data
  • 0
    @joe вы можете конвертировать ref-содержащие данные в байты (некоторые из которых будут в основном бессмысленными - т.е. ссылки / указатели), но вы не сможете вернуться снова - в основном среда выполнения и CLR действительно не хотят, чтобы вы создавали - нулевые ссылки, которые являются недействительными - это нарушило бы всю семью предположений. Вы, конечно, можете сделать это с небезопасным кодом, но .... пожалуйста, не
Показать ещё 3 комментария

Ещё вопросы

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