【问题标题】:Remove SortedSet using BookSleeve使用 BookSleeve 移除 SortedSet
【发布时间】:2013-09-23 07:46:08
【问题描述】:

我尝试删除大约 336 个键,它们是 SortedSet,我在 Ubuntuserver 上使用 BookSleeve 作为 C3 客户端和 Redis。 下面的代码有效,但如果我删除 Console.WriteLine,它不会随机删除大约 100 个键。它不会引发任何错误,当我在 redis 服务器端打开 Montior 时,我看不到为那些没有从 c# 端删除的人发送 ZREM 声明。 为什么它可以与存在的 Console.Writeline 一起使用,而不是在它被注释掉的时候让我感到困惑。有什么想法吗?

public virtual void RemoveKey(string item, string id)
{
   for (int i = 1; i <= item.Length; i++)
   {
      Console.WriteLine(PrefixKey + item.Substring(0, i));
      _redisClient.SortedSets.Remove(_database, 
             PrefixKey + item.Substring(0, i), id);
   }
}

我有课

 public class RedisRepository
    {
        protected static RedisConnection _redisClient;
        protected int _database;
        protected bool disposed;

        public RedisRepository(int database)
        {
            string server = ConfigurationManager.AppSettings["redis.server"];
            int port = Convert.ToInt32(ConfigurationManager.AppSettings["redis.port"]);
            string password = ConfigurationManager.AppSettings["redis.password"];
            _redisClient = new RedisConnection(server, port, -1, password);
            _database = database;
            _redisClient.Open();
        }
     ~RedisRepository()
        {
            this.Dispose(false);
        }

        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);

        }

        protected virtual void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if (disposing)
                {
                    _redisClient.CloseAsync(false);
                    _redisClient.Dispose();
                }

                // Dispose unmanaged resources here.
            }

            disposed = true;
        }
}

我已将上面的 RedisRpository 类继承到另一个使用其 _redisClient 对象的类中。

【问题讨论】:

  • 什么是_redisClient和_database?

标签: c# c#-4.0 redis booksleeve


【解决方案1】:

如果没有看到 _redisClient 的生命周期,这有点难以回答。特别是 RedisConnection 的所有操作都是异步的。如果您正在运行一个启动操作然后立即存在的测试:有些东西可能仍在套接字上等待。如果 redis 检测到套接字关闭,它会立即终止该连接(它甚至不会先耗尽套接字,因此忽略挂起的操作)。如果您的进程终止,套接字将突然关闭。

但是,如果您使用“using”,它应该可以正常工作 - dispose 实现应该确保它正确关闭。

所以基本上这会很糟糕:

static void Main() {
    var conn = OpenConnection();
    // lots of operations
}

但这应该没问题:

static void Main() {
    using(var conn = OpenConnection()) {
         // lots of operations
    }
}

或者,您可以跟踪最后一次操作并简单地等待:

Task last = null;
for(...) {
     last = conn.SomeOperation(...);
}
if(last != null) conn.Wait(last);

如果它与其中任何一个都不相关,那么一个完整的例子真的会有所帮助......

【讨论】:

  • 我已经添加了我如何实现 redis 连接
  • @JustinHomes 编辑在它被杀死时仍然没有显示我 - 它只是移动了问题。现在,例如,问题是“好的,RedisRepository 什么时候处理?” - 因为如果我们用new RedisRepository()替换OpenConnection(),完全相同的“这应该是坏的”和“这应该没问题”的例子仍然同样适用
  • 我在退出控制台应用程序之前添加了 5 秒的睡眠时间,它成功了。我猜控制台应用程序在线程完成之前就退出了??
  • @JustinHomes 再次,如果没有看到控制台 exe 的结构,我无法直接对此发表评论。最好的方法是在最后一个结果上添加usingWait - 如示例所示。等待随机的时间不是,IMO,最好的方法。
  • 我确实有等待创建 redis 连接实例的任务线程,但是我如何添加等待对 redis 进行异步调用的书架库线程?
【解决方案2】:

也许您必须等到异步删除完成。

试试这个代码:

public virtual void RemoveKey(string item, string id)
{
   Task[] removeTasks = new Task[item.Length];
   for (int i = 1; i <= item.Length; i++)
   {
      Console.WriteLine(PrefixKey + item.Substring(0, i));
      removeTasks[i-1] = _redisClient.SortedSets.Remove(_database, 
             PrefixKey + item.Substring(0, i), id);
   }

   _redisClient.WaitAll(removeTasks);
}

【讨论】:

  • 这个不应该至少是必需的:理论上是这样
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-21
  • 1970-01-01
  • 2013-01-31
  • 2012-03-11
  • 1970-01-01
相关资源
最近更新 更多