C# Redis书套插座
使用BookSleeve连接并向Redis服务器添加/获取条目时,我收到SocketException。具体的例外情况是:每个套接字地址(协议/网络地址/端口)通常只允许使用一次。 堆栈跟踪指向d:\Dev\booksleve\booksleve\RedisConnectionBase.cs:2050中的:C# Redis书套插座,c#,sockets,redis,booksleeve,C#,Sockets,Redis,Booksleeve,使用BookSleeve连接并向Redis服务器添加/获取条目时,我收到SocketException。具体的例外情况是:每个套接字地址(协议/网络地址/端口)通常只允许使用一次。 堆栈跟踪指向d:\Dev\booksleve\booksleve\RedisConnectionBase.cs:2050中的:booksleve.RedisConnectionBase.Wait(任务任务) 我的问题是,我的代码中是否有错误(很可能)没有正确地关闭连接或类似的事情?异常通常在大约60秒内执行16000
booksleve.RedisConnectionBase.Wait(任务任务)
我的问题是,我的代码中是否有错误(很可能)没有正确地关闭连接或类似的事情?异常通常在大约60秒内执行16000次操作后抛出。这似乎不是一个过多的操作量,对吗
相关代码如下,我很乐意提供任何其他信息
public Cache.CacheEntry Get(string key, bool updateAccessed)
{
var cacheKey = GetCacheableKey(key);
using (var conn = GetUnsecuredConnection())
{
var entry = conn.Get<Cache.CacheEntry>(cacheKey);
return entry;
}
}
public override void Add(string key, Cache.CacheEntry entry)
{
var cacheKey = GetCacheableKey(key);
using (var conn = GetUnsecuredConnection())
{
using (var trans = conn.CreateTransaction())
{
trans.Set(cacheKey, entry);
trans.Strings.Increment(DbNum, CacheEntryCountKey);
trans.Strings.Increment(DbNum, CacheSizeKey, entry.DataLength);
trans.Sets.Add(DbNum, CacheKeysKey, cacheKey);
trans.Execute();
}
}
}
RedisConnection对象的常规扩展方法:
public static T Get<T>(this RedisConnection conn, string key, int dbNum = 0)
{
if (typeof (T) == typeof (byte[]))
{
var task = conn.Strings.Get(dbNum, key);
var result = conn.Wait(task);
return (T) (object) result;
}
else
{
var task = conn.Strings.GetString(dbNum, key);
var result = conn.Wait(task);
if (result == null || typeof(T) == typeof(string))
return (T)(object)result;
return JsonSerializer.DeserializeFromString<T>(result);
}
}
public static void Set<T>(this RedisConnection conn, string key, T value, int dbNum = 0)
{
if (typeof (T) == typeof (byte[]))
{
conn.Strings.Set(dbNum, key, value as byte[]);
return;
}
var serializedValue = JsonSerializer.SerializeToString(value);
conn.Strings.Set(dbNum, key, serializedValue);
}
public static T Get(此重新连接连接,字符串键,int dbNum=0)
{
if(typeof(T)=typeof(byte[]))
{
var task=conn.Strings.Get(dbNum,key);
var结果=连接等待(任务);
返回(T)(对象)结果;
}
其他的
{
var task=conn.Strings.GetString(dbNum,key);
var结果=连接等待(任务);
if(result==null | | typeof(T)==typeof(string))
返回(T)(对象)结果;
返回JsonSerializer.DeserializeFromString(结果);
}
}
公共静态无效集(此重新连接连接,字符串键,T值,int dbNum=0)
{
if(typeof(T)=typeof(byte[]))
{
Set(dbNum,key,值为字节[]);
返回;
}
var serializedValue=JsonSerializer.SerializeToString(值);
Set(dbNum、key、serializedValue);
}
马克对这个问题的评论让我重新考虑我是如何利用人际关系的。我找到了另一个问题的答案:
我最终使用了上面链接答案中的代码,删除了我发布的“GetUnsecuredConnection”方法,现在在构造/执行Redis操作之前只检索打开的连接
再也没有SocketException了,一切似乎都按预期进行。谢谢你的提示,马克!感谢@ofer zelig提供的连接代码
public Cache.CacheEntry Get(string key, bool updateAccessed)
{
var cacheKey = GetCacheableKey(key);
var conn = RedisConnectionGateway.Current.GetConnection();
var entry = conn.Get<Cache.CacheEntry>(cacheKey);
return entry;
}
public override void Add(string key, Cache.CacheEntry entry)
{
var cacheKey = GetCacheableKey(key);
var conn = RedisConnectionGateway.Current.GetConnection();
using (var trans = conn.CreateTransaction())
{
trans.Set(cacheKey, entry);
trans.Strings.Increment(DbNum, CacheEntryCountKey);
trans.Strings.Increment(DbNum, CacheSizeKey, entry.DataLength);
trans.Sets.Add(DbNum, CacheKeysKey, cacheKey);
trans.Execute();
}
}
public Cache.CacheEntry获取(字符串键,bool updateAccessed)
{
var cacheKey=GetCacheableKey(key);
var conn=RedisConnectionGateway.Current.GetConnection();
var entry=conn.Get(cacheKey);
返回条目;
}
公共覆盖无效添加(字符串键,Cache.CacheEntry)
{
var cacheKey=GetCacheableKey(key);
var conn=RedisConnectionGateway.Current.GetConnection();
使用(var trans=conn.CreateTransaction())
{
事务集(缓存键、条目);
增量(DbNum,CacheEntryCountKey);
trans.Strings.Increment(DbNum、CacheSizeKey、entry.DataLength);
trans.Sets.Add(DbNum,CacheKeysKey,cacheKey);
trans.Execute();
}
}
您多久创建一次新实例?因为它是一个多路复用器,所以广泛地重用实例是正常的。但我从未见过这种行为!似乎正在为每个操作创建新的实例,这似乎不太理想。这就是我以单元测试为例得到的结果:)
public Cache.CacheEntry Get(string key, bool updateAccessed)
{
var cacheKey = GetCacheableKey(key);
var conn = RedisConnectionGateway.Current.GetConnection();
var entry = conn.Get<Cache.CacheEntry>(cacheKey);
return entry;
}
public override void Add(string key, Cache.CacheEntry entry)
{
var cacheKey = GetCacheableKey(key);
var conn = RedisConnectionGateway.Current.GetConnection();
using (var trans = conn.CreateTransaction())
{
trans.Set(cacheKey, entry);
trans.Strings.Increment(DbNum, CacheEntryCountKey);
trans.Strings.Increment(DbNum, CacheSizeKey, entry.DataLength);
trans.Sets.Add(DbNum, CacheKeysKey, cacheKey);
trans.Execute();
}
}