C# 结构到它';s ReadOnlyMemory<;字节>;代表

C# 结构到它';s ReadOnlyMemory<;字节>;代表,c#,.net-core,system.memory,C#,.net Core,System.memory,我有以下结构: [StructLayout(LayoutKind.Sequential)] struct Message { int Header; int Data; } 我想通过无线方式发送它,不需要分配(使用SendAsync(ReadOnlyMemory))调用 如何从给定的结构中获取内存 我最终陷入了Span,然后陷入困境 var message = new Message { Header = 1, Data = 3 }; var bytes = Memor

我有以下结构:

[StructLayout(LayoutKind.Sequential)]
struct Message
{
     int Header;
     int Data;
}
我想通过无线方式发送它,不需要分配(使用
SendAsync(ReadOnlyMemory)
)调用

如何从给定的结构中获取
内存

我最终陷入了
Span
,然后陷入困境

var message = new Message {
  Header = 1, Data = 3
};
var bytes = MemoryMarshal.AsBytes(
    MemoryMarshal.CreateReadOnlySpan(ref message, 1)
);
有没有办法不进行任何分配就直接将结构放入流中

我使用的是
netcoreapp2.1

类似于:

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

不过,诀窍是使用
MemoryMarshal.Cast(…)
获得一个字节跨度。

跨度只能存在于堆栈上。异步方法需要其参数至少与任务本身一样长。因此,如何确保跨度一直持续到任务结束?你不能,所以为什么这些方法使用内存,它可以活得更长。这意味着您无论如何都需要复制它。@EtienDemartel我的
消息
无论如何都是在AsyncStateMachine中捕获的-它不是
ref struct
。无论如何,标题有误导性。我会更新它。很好,但是如果
消息
包含一个引用或类似指针的字段,有什么方法可以更新它吗?比方说一个
byte[]data
@joe你可以将包含数据的ref转换成字节(其中一些字节基本上没有意义,例如引用/指针),但是你不能再返回了-基本上,运行时和CLR真的不希望你创建无效的非零引用-这将违反一系列假设。当然,您可以使用不安全的代码,但是。。。。请不要♦ 为什么它毫无意义?在很多情况下,我有一个结构,里面有
int
byte[]
对象
,我需要一个内存(内存应该保留引用/指针,而不是数据本身)。但在这种情况下,我不能执行ref->data字节。不允许我这样做。它不能包含引用或指针。我明白我们不应该回去。但是为什么我们有这个前进限制?@joe引用只是具有语义意义的指针,但是。。。仍然只是随机的ish数字,如果GC选择,它将在每次运行或运行期间更改,并且不能有效地解释;下面的代码正好显示了这一点,所以它是可能的-只是。。。没用:@joe note我不得不跳转到
safe
code才能作为span返回;不过,你可以不用担心-
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)