为什么 Read 和 ReadAync 产生完全不同的结果

Why Read and ReadAync are producing totally different results

我一直在使用 this code 来捕捉网络摄像头,我一直在努力从中学习并使它变得更好。骑手 IDE 建议我应该使用 MemoryMappedViewStream.Read 的异步变体,但它根本不起作用。它生成全黑图像,表明异步和同步方法完全不同。我想知道为什么会这样?

// Working:
sourceStream.Read(MemoryMarshal.AsBytes(image.GetPixelMemoryGroup().Single().Span));

// NOT Working:
var bytes = MemoryMarshal.AsBytes(image.GetPixelMemoryGroup().Single().Span).ToArray();
await sourceStream.ReadAsync(bytes, 0, bytes.Length, token);

Repository and line of code

await sourceStream.ReadAsync(bytes, 0, bytes.Length, token).ConfigureAwait(false);

这样检查

这两个版本不一样。在“同步”版本中,您可以通过 image.GetPixelMemoryGroup() 获取对图像内存位置的引用。然后,您将 sourceStream 中的数据直接读取到该位置。

在“异步”版本中,您再次通过 image.GetPixelMemoryGroup 获取对内存位置的引用,但随后您做了一些不同的事情 - 您调用 ToArray。此扩展方法 将图像内存位置中的 字节复制到新数组中,即您保存在 bytes 变量中的数组。然后,您将数据从 sourceStream 读入 bytes 数组,而不是直接读入图像内存位置。然后你丢弃 bytes 数组,所以你基本上没有读到它们。

现在,MemoryMappedViewStream 继承自 UnmanagedMemoryStream,所有 read\write 操作都在 UnmanagedMemoryStream 中实现。这种流表示内存中的数据,异步无能为力。它甚至具有 ReadAsync 的唯一原因是因为基本流 class (Stream) 具有这些方法。即使你设法让 ReadAsync 工作——在这种情况下它也不会是异步的。据我所知 - MemoryMappedViewStream 现在允许真正的异步访问,即使它可能有意义,因为它有底层文件。

简而言之 - 我将继续使用同步版本,因为在这种情况下使用“异步”版本没有任何好处。静态分析器当然不知道,它只看到你使用的方法有 Async-named 模拟。