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谢谢,我会这样做,事实上我用这种方式解决了这个问题,也许不是最好的,但也许可以帮助别人,不管怎样,我只是把这个标记为回答,因为没有其他人有不同的想法。再次感谢!