4

我正在尝试在 C# 中使用 Redis 编写生产者/消费者系统。产生的每条消息只能由一个消费者消费,我希望消费者等待消费者创建的元素。我的系统必须支持许多生产/消费者集。

StackExchange.Redis用来与 Redis 进行通信,并使用列表来添加ListLeftPush和删除元素ListRightPop。我遇到的是,虽然该ListRightPop方法应该阻塞直到列表中存在一个元素(或在定义的超时之后),但如果列表中没有元素,它总是自动返回。这是我为检查而编写的测试代码:

IDatabase cache = connection.GetDatabase();        
Trace.TraceInformation("waiting "+DateTime.Now);
var res = cache.ListRightPop("test");
Trace.TraceInformation("Got "+res+", Ended" + DateTime.Now);

nil不到 1 秒我就得到了结果。

4

2 回答 2

7

标准的弹出操作不会阻塞:如果列表为空或不存在,它们会返回 nil。

SE.Redis 是一个多路复用器。使用阻塞弹出是一个非常非常糟糕的主意。在文档中对此进行了更多解释,并专门讨论了用于阻止弹出的解决方法:https ://stackexchange.github.io/StackExchange.Redis/PipelinesMultiplexers

于 2014-09-09T16:37:35.643 回答
2

StackExchange.Redis 只是在访问 redis 服务器公开的 API,BRPOP在您的情况下,相关方法就是如此。为此的文档是:

http://redis.io/commands/blpop - 阻止左弹出

http://redis.io/commands/brpop - 阻止右弹出

虽然这些方法确实描述了您正在寻找的阻塞行为,但我相信 SE.RedisListRightPop正在调用

http://redis.io/commands/rpop - 右弹出

我可能无法使用最新的 SE.Redis 软件包,但智能感知并没有像您声称的那样让我选择提供超时。此外,界面中似乎没有任何以“block”开头.List的方法IDatabase,所以我不确定 SE.Redis 是否公开了 Redis BRPOPAPI。您可以自己编写或很好地询问 Marc Gravell,但我认为这是一个非常大的请求,因为调用的阻塞性质和多路复用器的工作方式。

于 2014-09-09T15:45:03.010 回答