我正在尝试创建一个 .NET Core 应用程序,但在 IPC 上有点卡住了。
我有数据通过可执行文件 1 进入(比如说,来自套接字或文件,某种流接口)。现在,我希望可执行文件 2 读取这些数据。所以,我创建了一个 MMF,其中可执行文件 1 写入数据,可执行文件 2 读取数据。一切都很好。
但是,我真的很想跳过这里的“复制”步骤。如果我有通过套接字传入的消息,我需要读取消息(ergo;将其存储在某个字节数组中),然后将其复制到适当的内存映射文件中。
有没有办法让他们使用相同的内存(尤其是现在,有了新的内存、跨度等)?
这段代码似乎几乎可以工作,但并不完全:
const int bufferSize = 1024;
var mappedFile = MemoryMappedFile.CreateNew("IPCFile", bufferSize);
var fileAccessor = mappedFile.CreateViewAccessor(0, bufferSize, MemoryMappedFileAccess.ReadWrite);
// THere now exists a region of byte[] * bufferSize somewhere. I want to write to that.
byte[] bufferMem = new byte[bufferSize];
// I know the memory address where this area is, and I know the size of it:
unsafe
{
byte* startOfRegion = (byte*)0;
fileAccessor.SafeMemoryMappedViewHandle.AcquirePointer(ref startOfRegion);
// But how do I "assign" this region to the managed object?
// This throws "System.MissingMethodException: 'No parameterless constructor defined for type 'System.Byte[]'."
//bufferMem = Marshal.PtrToStructure<byte[]>(new IntPtr(startOfRegion));
// This almost looks like it works, but bufferMem remains null. Does not give any errors though.
bufferMem = Unsafe.AsRef<byte[]>(startOfRegion);
}
// For a shorter example, just using a file stream
var incomingData = File.OpenRead(@"C:\Temp\plaatje.png");
// Pass in the "reserved" memory region. But StreamPipeReaderOptions wants a MemoryPool<byte>, not a byte[].
// How would I cast that? MemoryPool is abstract, so can't even be instantiated
var reader = PipeReader.Create(incomingData, new StreamPipeReaderOptions(bufferMem));
ReadResult readResult;
// Actually read data
while (true)
{
readResult = await reader.ReadAsync();
if (readResult.IsCompleted || readResult.IsCanceled)
break;
reader.AdvanceTo(readResult.Buffer.Start, readResult.Buffer.End);
}
// Now signal the other process to read the contents of the MMF and continue
这个问题似乎问了类似的事情,但没有答案,并且是从2013年开始的。