C# 单例词典不是单例词典
我在一个单身班上有一本字典。我在那里保存这一对,每次我从创建令牌的方法访问字典时,它都会显示我存储在那里的所有凭据 但是,当我从解决方案的另一个项目中的另一个类访问时,字典显示为空。有人能告诉我为什么会这样吗 这是管理字典的类:C# 单例词典不是单例词典,c#,.net,dictionary,singleton,access-token,C#,.net,Dictionary,Singleton,Access Token,我在一个单身班上有一本字典。我在那里保存这一对,每次我从创建令牌的方法访问字典时,它都会显示我存储在那里的所有凭据 但是,当我从解决方案的另一个项目中的另一个类访问时,字典显示为空。有人能告诉我为什么会这样吗 这是管理字典的类: public class UserAccessToken { public Dictionary<string, string> UserDictionary { get; set; } private static UserAccessT
public class UserAccessToken
{
public Dictionary<string, string> UserDictionary { get; set; }
private static UserAccessToken _instance;
private UserAccessToken() { }
public static UserAccessToken Instance
{
get
{
if (_instance == null)
_instance = new UserAccessToken
{
UserDictionary = new Dictionary<string, string>()
};
return _instance;
}
}
}
public override Task TokenEndpointResponse(OAuthTokenEndpointResponseContext context)
{
var accessToken = context.AccessToken;
if (context.Properties.Dictionary.ContainsKey("userName"))
{
var username = context.Properties.Dictionary["userName"];
// If I access here multiple times the singleton works
UserAccessToken.Instance.UserDictionary[username] = accessToken;
}
return Task.FromResult<object>(null);
}
private bool IsTokenValid(HttpContextBase httpContext)
{
var username = httpContext.User.Identity.Name;
var userTokens = UserAccessToken.Instance.UserDictionary;
var tokenToAccess = httpContext.Request.Headers["Authorization"];
tokenToAccess = tokenToAccess.Replace("Bearer ", "");
if (userTokens.ContainsKey(username))
{
var token = userTokens[username];
if (token == tokenToAccess) return true;
}
return true;
}
我已经解决了我的问题,但我会把我的解决方案放在这里,以防对某人有用 问题是,如果你正在运行两个不同的项目,这将意味着两个不同的过程,所以,我想做的是非常不可能的。我用过这个,效果很好 这是Redis使用的一个示例:
public class CallManagerCache : ICallManagerMethods{
private static Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer
.Connect(CloudConfigurationManager.GetSetting("RedisConnectionString")));
public static ConnectionMultiplexer cacheConnection
{
get
{
return lazyConnection.Value;
}
}
/// <summary>
/// Here you save the value in cache, you get the connection, then StringSetAsync is in charge of saving the value
/// </summary>
/// <param name="name"></param>
/// <param name="template"></param>
public async Task UpdateCallInstance(int id, byte[] data, bool instanceForCallback = false, TimeSpan? timespan = null)
{
var cache = cacheConnection.GetDatabase();
await cache.StringSetAsync(instanceForCallback ? $"Call_{id}" : id.ToString(), data, timespan ?? new TimeSpan(0, 0, 15, 0));
}
/// <summary>
/// Here you get the value in cache, you get the connection, then StringGetAsync is in charge of getting the value
/// </summary>
/// <param name="name"></param>
/// <param name="template"></param>
public async Task<CallInstance> GetById(int id, bool isForCallback)
{
var cache = cacheConnection.GetDatabase();
var callInstance = new CallInstance
{
Id = id,
InstanceData = await cache.StringGetAsync(isForCallback ? $"Call_{id}" : id.ToString())
};
return callInstance;
}
}
公共类CallManagerCache:ICallManagerMethods{
私有静态惰性lazyConnection=新惰性(()=>ConnectionMultiplexer
.Connect(CloudConfigurationManager.GetSetting(“RedisConnectionString”);
公共静态连接多路复用器缓存连接
{
得到
{
返回lazyConnection.Value;
}
}
///
///在这里,您将值保存在缓存中,获得连接,然后StringSetAsync负责保存值
///
///
///
公共异步任务UpdateCallInstance(int-id,字节[]数据,bool-instanceForCallback=false,TimeSpan?TimeSpan=null)
{
var cache=cacheConnection.GetDatabase();
wait cache.StringSetAsync(instanceForCallback?$“Call_{id}”:id.ToString(),数据,timespan??新timespan(0,0,15,0));
}
///
///在这里,您在缓存中获取值,获得连接,然后StringGetAsync负责获取值
///
///
///
公共异步任务GetById(int-id,bool-isForCallback)
{
var cache=cacheConnection.GetDatabase();
var CALINSTANCE=新CALINSTANCE
{
Id=Id,
InstanceData=Wait cache.StringGetAsync(isForCallback?$“Call_{id}”:id.ToString()
};
返回callInstance;
}
}
这两个访问是否在同一个线程上?您认为单例实现不是线程安全的。“来自另一个项目中的另一个类”,所以它可能也是另一个进程?当然,对于不同的进程,您的实例
是不同的。Jon Skeet在C#中有一个关于单例的深入讨论。查看线程安全示例(我最喜欢的是使用Lazy
),请阅读关于发布代码的指南。有太多不相关的代码显示,实际上没有足够的信息来理解问题。也就是说,@RenéVogt指出,代码可能在单独的进程中运行,或者至少在单独的线程中运行(如图所示,代码使用的是非线程安全的字典
,没有锁定)。。。请注意,如果在一个进程中同步地在同一线程上执行,则所示代码可以正常工作。如果两个线程同时添加/更新用户令牌,则会出现问题。您应该切换到ConcurrentDictionary这只是一个建议:查看Windows服务
或某种类型的数据库。我相信你会得到你想要的。但是如果你已经解决了你已经解决了。。。对于你正在做的事情来说,这似乎不是正确的解决方案,但如果它工作正常,谁又该责怪你呢。@MichaelPuckettII谢谢,我会这样做,事实上我用这种方式解决了这个问题,也许不是最好的,但也许可以帮助别人,不管怎样,我只是把这个标记为回答,因为没有其他人有不同的想法。再次感谢!