1

SortedSets を削除しようとしている約 336 個のキーがあります。Ubuntuserver で Redis を使用して BookSleeve を C3 クライアントとして使用しています。 以下のコードは機能しますが、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 オブジェクトを使用する別のクラスに継承しました。

4

2 に答える 2

1

これは、_redisClient のライフタイム サイクルを確認せずに答えるのは少し難しいです。特に、RedisConnection のすべての操作は非同期です。操作を開始してすぐに存在するテストを実行している場合: ソケットでまだ待機しているものがある可能性があります。redis がソケットのクローズを検出すると、その接続をすぐに強制終了します (最初にソケットを空にすることさえしないため、保留中の操作は無視されます)。プロセスが終了すると、ソケットは突然閉じます。

ただし、「using」を使用している場合は、正常に動作するはずです。破棄の実装により、適切に閉じられていることが保証されます。

したがって、基本的にこれは悪いことです:

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);

これらのいずれにも関係がない場合は、完全な例が本当に役立ちます...

于 2013-09-22T08:31:43.210 に答える
0

非同期の削除が完了するまで待つ必要があるかもしれません。

このコードを試してください:

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);
}
于 2013-09-22T07:47:35.187 に答える