在TPL Dataflow TransformBlock中使用DeflateStream和/或CryptoStream的用法

3
我正在使用TPL Dataflow blocks来实现基于数据包的网络协议。该协议是固定的,我无法更改。通常会有许多小的数据包。
我有一个客户端组件连接到服务器并读取原始数据包。这些原始数据包随后被作为MemoryStreams发布到BufferBlock中,并在TransformBlock中解码成数据包结构体,具体取决于数据包类型/ID。
为了发送数据包,这个过程被反转,并使用另一条数据流块链。就我所知,所有这些都能很好地工作。
问题在于这些数据包可能会或可能不会被压缩和加密,这取决于服务器响应。我可以通过添加新的TransformBlocks来解决这个问题(以解压为例):
static TransformBlock<Stream, Stream> CreateDecompressorBlock(ProtocolContext context)
{
    return new TransformBlock<Stream, Stream>(stream =>
    {
        if (!context.CompressionEnabled) return stream;
        return new DeflateStream(stream, CompressionMode.Decompress);
    }
}

然而,这对我来说似乎不是正确的方法。据我所知,DeflateStream(和CryptoStream)在读取数据时解码数据。这意味着,当我解码数据块内容时,数据已经被解码,而不是在TransformBlock中创建包装器Stream时解码。这似乎会规避Dataflow Blocks的优点。

因此,我想到另一个解决方案,即不返回DeflateStream/CryptoStream,而是将其读入另一个MemoryStream中:

static TransformBlock<Stream, Stream> CreateDecompressorBlock(ProtocolContext context)
{
    return new TransformBlock<Stream, Stream>(stream =>
    {
        if (!context.CompressionEnabled) return stream;
        using (var deflate = new DeflateStream(stream, CompressionMode.Decompress))
        {
            var ms = new MemoryStream();
            deflate.CopyTo(ms);
            return ms;
        }
    }
}

现在看来,这似乎是一种浪费内存的做法。

所以我的问题是,仅仅包装流并让稍后解码数据包内容的TransformBlock来完成工作是否足够,或者我应该使用更多的内存,然后实现更好的分离和可能的并行性呢?(虽然我不认为解码会成为瓶颈,因为网络才是瓶颈)。

或者有没有TPL Dataflow中可以更好地解决我的问题的模式?


1
选择相当直截了当。只有您可以判断每种方法的优点。如果您明确想要区分解码阶段(也许这样您可以更好地管理资源/并发),那么将解码到MemoryStream似乎是一个不错的主意,但在内存方面更加昂贵。另一方面,如果您的数据包解析TransformBlock没有受到额外解码负载的CPU限制,就让流发挥它们的魔力吧... - spender
唯一可能出现问题的情况是在您承受重负并且队列/端口(或者在TPLDF中称为什么)开始积压时。当您遇到这种情况时,仔细测量很可能会给您更好的答案。 - spender
你为什么要把这个放到一个单独的块中呢?为什么不直接添加到现有的块中呢? - svick
1个回答

1

像往常一样,这是一个权衡,决定只能由您做出。

我会选择最简单的解决方案,即连接两个块,并让写入块“吸收”添加的压缩复杂性,因为 TDF 块在需要时可以增加其并行性。 但是,如果该块没有限制并行性 (MaxDegreeOfParallelism),我只会这样做。

如果有限制,那么我将像您描述的那样在压缩块中处理实际压缩。这种行为可以以非常高的并行度完成,并且这些内存缓冲区似乎并不是什么大问题。

如果它们是问题,您可以添加一个缓冲池,因此您的缓冲区计数将限制在块的 MaxDegreeOfParallelism 中,并且您只需要在应用程序的生命周期中分配这些缓冲区一次。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接