到目前为止,我们一直在使用所谓的“Unbounded”通道。你会注意到,当我们创建通道时,我们这样做:
var myChannel = Channel.CreateUnbounded<int>();
但实际上,我们可以这样做:
var myChannel = Channel.CreateBounded<int>(1000);
这与创建容量有限的列表或数组等其他集合类型并无太大差别。在我们的示例中,我们创建了一个最多容纳1000项的Channel。但为什么要限制自己呢?这就是背压的作用。
什么是背压?
背压(特别是当涉及消息传递/排队时)是指资源(无论是内存、ram、网络)是有限的。我们应该能够在链条上施加“压力”,试着减轻一些压力。至少,让生态系统中的其他人知道我们负荷过重,我们可能需要一些时间来处理他们的请求。
一般来说,当我们讨论队列的背压时。几乎所有情况下,我们都在讨论一种方法,告诉任何试图在队列中添加更多条目的人,要么他们根本无法再加入任何条目,要么他们需要推后一段时间。更罕见的是,我们讨论的队列是在达到一定容量时纯粹丢弃消息。这种情况很少发生,但是我们有这个选项。
那么它是如何与.net Channel一起工作的呢?
Channel中的背压
当使用通道时,我们实际上有一个非常简单的方法来增加背压。代码看起来是这样的:
var channelOptions = new BoundedChannelOptions(5) { FullMode = BoundedChannelFullMode.Wait }; var myChannel = Channel.CreateBounded<int>(channelOptions);
我们可以指定以下完整模式:
等待
在打开WriteAsync()调用之前,只需让调用者等待。
DropNewest / DropOldest
可以在Channel中拖放最老的或最新的项目,为我们想要添加的项腾出空间。
DropWrite
简单地转储我们应该写的消息。
还有另外两段代码需要注意。
你可以调用WaitToWriteAsync():
await myChannel.Writer.WaitToWriteAsync();
这让我们Channel成了有界。当Channel已满时,我们可以简单地等待,直到有空间。这意味着,即使打开了DropWrite FullMode,我们也可以通过简单地等待,直到有容量为止,来限制扔在地面上的消息数量。
我们应该注意的另一段代码是:
var success = myChannel.Writer.TryWrite(i);
这允许我们尝试写入队列,并返回,无论成功与否。需要注意的是,此方法不是异步的。要么写入信道要么不写入信道,这里没有”如果你再多等一会儿,也许可以。”
欢迎关注我的公众号,如果你有喜欢的外文技术文章,可以通过公众号留言推荐给我。
原文链接:https://dotnetcoretutorials.com/2020/11/24/using-channels-in-net-core-part-3-understanding-back-pressure/