我正在尝试使用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);
我在不到1秒的时间内得到nil
结果。
答案 0 :(得分:5)
标准弹出操作不会阻止:如果列表为空或不存在,则返回nil。
SE.Redis是一个多路复用器。使用阻塞弹出是一个非常糟糕的主意。在文档中https://stackexchange.github.io/StackExchange.Redis/PipelinesMultiplexers
对此进行了更多解释,并专门讨论了阻止弹出窗口的变通方法答案 1 :(得分:2)
StackExchange.Redis只是点击了redis服务器公开的API,其相关方法是BRPOP
。该文件是:
http://redis.io/commands/blpop - 阻止左侧弹出
http://redis.io/commands/brpop - 阻止右键弹出
虽然这些方法确实描述了您正在寻找的阻止行为,但我相信SE.Redis ListRightPop
正在调用
http://redis.io/commands/rpop - 右键弹出
我可能没有达到最新的SE.Redis软件包,但是intellisense没有给我一个选项来提供你声称的超时。此外,似乎没有任何方法以.List
接口中的IDatabase
开头,其中包含" block"在其中,所以我不确定SE.Redis是否公开了Redis BRPOP
API。您可以自己编写或者很好地询问Marc Gravell,但我认为这是一个非常大的请求,因为调用的阻塞性和多路复用器的工作方式。