是否有人可以通过BookSleeve库获取Redis的固定模式?
我的意思是:
BookSleeve的作者@MarcGravell 建议不要每次都打开和关闭连接,而是在整个应用程序中保持一个连接。但是如何处理网络中断?也就是说,连接可能首先成功打开,但是当某些代码尝试对Redis进行读/写操作时,连接可能已断开,您必须重新打开它(如果连接无法打开,则正常失败- 但是完全可以满足您的设计需求。)
我寻求覆盖常规Redis连接打开的代码段,以及将在每次读/写之前使用的常规“活动”检查(如果未激活,则可选地唤醒)。
这个问题有很好的态度,但是它只是局部的(例如,它不能恢复丢失的连接),并且对该问题的公认答案画出了正确的方法,但是没有展示具体的代码。
我希望该线程能够得到可靠的答案,并最终成为.Net应用程序中有关BookSleeve的一种Wiki。
-----------------------------
重要更新(21/3/2014):
马克Gravell(@MarcGravell)/堆栈交易所已经最近发布的StackExchange.Redis库,最终取代Booksleeve。这个新的库除其他外,在内部处理重新连接并使我的问题变得多余(也就是说,对于Bookleeve或下面的答案来说,这不是多余的,但我认为最好的方法是开始使用新的StackExchange.Redis库)。
由于我没有任何好的答案,所以我想出了这个解决方案(顺便说一句,感谢@Simon和@Alex的回答!)。
我想与所有社区分享作为参考。当然,任何更正将不胜感激。
using System; using System.Net.Sockets; using BookSleeve; namespace Redis { public sealed class RedisConnectionGateway { private const string RedisConnectionFailed = "Redis connection failed."; private RedisConnection _connection; private static volatile RedisConnectionGateway _instance; private static object syncLock = new object(); private static object syncConnectionLock = new object(); public static RedisConnectionGateway Current { get { if (_instance == null) { lock (syncLock) { if (_instance == null) { _instance = new RedisConnectionGateway(); } } } return _instance; } } private RedisConnectionGateway() { _connection = getNewConnection(); } private static RedisConnection getNewConnection() { return new RedisConnection("127.0.0.1" /* change with config value of course */, syncTimeout: 5000, ioTimeout: 5000); } public RedisConnection GetConnection() { lock (syncConnectionLock) { if (_connection == null) _connection = getNewConnection(); if (_connection.State == RedisConnectionBase.ConnectionState.Opening) return _connection; if (_connection.State == RedisConnectionBase.ConnectionState.Closing || _connection.State == RedisConnectionBase.ConnectionState.Closed) { try { _connection = getNewConnection(); } catch (Exception ex) { throw new Exception(RedisConnectionFailed, ex); } } if (_connection.State == RedisConnectionBase.ConnectionState.Shiny) { try { var openAsync = _connection.Open(); _connection.Wait(openAsync); } catch (SocketException ex) { throw new Exception(RedisConnectionFailed, ex); } } return _connection; } } } }