StackExchange.Redis在for循环上流水线操作?

时间:2017-09-30 22:36:53

标签: c# .net redis stackexchange.redis

前言

我有一个简单的接口,它假设密钥之间存在依赖关系。 它的两个方法是:

  1. Remove(string key) - 从缓存中删除单个密钥。
  2. RemoveDependentsOf(string baseKey) - 删除baseKeybaseKey的所有家属。

    1. baseKey中指定了Redis set的家属。

    2. 因此,为了删除baseKey的所有家属,我必须阅读baseKey的设置,然后循环删除它们。

      < / LI>
  3. 问题

    我读了 StackExchange.Redis 文档,所以我知道他们传奇的流水线支持,并根据他们的文档,以下代码应该非常有效。

    但是,我似乎无法理解库如何管道KeyDelete命令,因为该方法返回一个布尔值,无论该键是否被删除

    因此,在执行第二个KeyDelete命令之前,应该先发送第一个命令并接收其响应(这样做效率不高)。

    • 我在这里缺少什么?
    • 我应该如何编写以下代码?
    public void Remove(string key)
    {
        _redis.KeyDelete(key);
    }
    
    public void RemoveDependentsOf(string key)
    {
        Remove(key);
    
        var setKey = GetDependencySetKey(key);
        RedisValue[] dependents = _redis.SetMembers(setKey);
        foreach (var dependentKey in dependents)
        {
            RemoveDependentsOf(dependentKey);
        }
    
        // This is the way to remove the whole set
        _redis.KeyExpire(setKey, TimeSpan.Zero);
    }
    

1 个答案:

答案 0 :(得分:3)

您正在使用同步方法,虽然您没有明确依赖KeyDelete操作的结果,但StackExchange.Redis并不知道您没有使用结果。因此,您无法获得图书馆提供的任何流水线优势。

文档明确地提出了两种可以使用流水线支持的方法;如果您想知道它何时完成或使用Fire and Forget,请使用Async方法并执行Task.WhenAll。您可以通过将CommandFlags.FireAndForget传递给命令(例如

)来明确告诉库您要执行此操作

_redis.KeyDelete(key, CommandFlags.FireAndForget)

请注意,这将导致从调用返回默认结果,而不是实际结果。鉴于你无视这些结果,你应该没事!