Service Stack Redis 连接的线程安全
Thread safety of Service Stack Redis connections
我最近在使用 Service Stack 时遇到了一些问题 - 我发现这似乎是由多个线程引起的,每个线程都连接到 Redis 以执行操作。如果我在任何时候只有一个线程 运行 它工作正常,但如果更多,我会收到几个不同的错误。我在别处看到最好使用 PooledRedisClientManager 并在其上调用 GetClient,但它仍然给我带来麻烦。我只想知道 Redis 是否是线程安全的,以及您可以采取哪些步骤来确保它不会在并发线程上中断。
我已经创建了一个专门用于测试的程序,如下所示。
class Program
{
static IRedisClient redis = new PooledRedisClientManager(ConfigurationManager.AppSettings["RedisServer"]).GetClient();
static void Main(string[] args)
{
LimitedConcurrencyLevelTaskScheduler scheduler = new LimitedConcurrencyLevelTaskScheduler(10);
List<Task> tasks = new List<Task>();
// Create a TaskFactory and pass it our custom scheduler.
TaskFactory factory = new TaskFactory(scheduler);
for (int i = 0; i < 100; i++)
{
Task task = factory.StartNew(() => AsyncMethod1(i));
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
for (int i = 0; i < 100; i++)
{
Task task2 = factory.StartNew(() => AsyncMethod2(i));
tasks.Add(task2);
}
Task.WaitAll(tasks.ToArray());
Console.ReadKey();
}
public static void AsyncMethod1(int i)
{
redis.SetEntry("RedisTest" + i, "TestValue" + i);
}
public static void AsyncMethod2(int i)
{
List<string> result = redis.ScanAllKeys("RedisTest" + i).ToList();
if (result[0] == "RedisTest" + i) Console.Out.Write("Success! " + result[0] + "\n");
else Console.Out.Write("Failure! " + result[0] + " :(\n");
}
}
您不应在多个线程之间共享 RedisClient 实例,因为它们不是 ThreadSafe。相反,您应该从线程安全的 Redis 客户端管理器中解析并释放它们 - also mentioned in the docs.
我最近在使用 Service Stack 时遇到了一些问题 - 我发现这似乎是由多个线程引起的,每个线程都连接到 Redis 以执行操作。如果我在任何时候只有一个线程 运行 它工作正常,但如果更多,我会收到几个不同的错误。我在别处看到最好使用 PooledRedisClientManager 并在其上调用 GetClient,但它仍然给我带来麻烦。我只想知道 Redis 是否是线程安全的,以及您可以采取哪些步骤来确保它不会在并发线程上中断。
我已经创建了一个专门用于测试的程序,如下所示。
class Program
{
static IRedisClient redis = new PooledRedisClientManager(ConfigurationManager.AppSettings["RedisServer"]).GetClient();
static void Main(string[] args)
{
LimitedConcurrencyLevelTaskScheduler scheduler = new LimitedConcurrencyLevelTaskScheduler(10);
List<Task> tasks = new List<Task>();
// Create a TaskFactory and pass it our custom scheduler.
TaskFactory factory = new TaskFactory(scheduler);
for (int i = 0; i < 100; i++)
{
Task task = factory.StartNew(() => AsyncMethod1(i));
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
for (int i = 0; i < 100; i++)
{
Task task2 = factory.StartNew(() => AsyncMethod2(i));
tasks.Add(task2);
}
Task.WaitAll(tasks.ToArray());
Console.ReadKey();
}
public static void AsyncMethod1(int i)
{
redis.SetEntry("RedisTest" + i, "TestValue" + i);
}
public static void AsyncMethod2(int i)
{
List<string> result = redis.ScanAllKeys("RedisTest" + i).ToList();
if (result[0] == "RedisTest" + i) Console.Out.Write("Success! " + result[0] + "\n");
else Console.Out.Write("Failure! " + result[0] + " :(\n");
}
}
您不应在多个线程之间共享 RedisClient 实例,因为它们不是 ThreadSafe。相反,您应该从线程安全的 Redis 客户端管理器中解析并释放它们 - also mentioned in the docs.