全局对象的不一致持久性

本文关键字:持久性 不一致 对象 全局 | 更新日期: 2023-09-27 18:18:49

我正在研究云托管的ZipFile创建服务。

这是一个跨域WebApi2服务,用于从不能承载任何服务器端代码的文件系统中提供ZipFiles。

基本操作如下:

  • 用户使用与文件位置相关的url的string[]发出POST请求
  • WebApi将数组读入内存,并创建一个票号WebApi将票号返回给用户AJAX回调,然后重定向用户到一个web地址与附加的票号,它返回压缩文件在HttpResponseMessage

为了处理票据系统,我的设计方法是建立一个全局字典,该字典将随机生成的10位数字配对为List<String>值,并将字典配对为Queue,每次存储10,000个条目。(参考这里)

部分原因是WebApi不支持缓存

当我在本地进行AJAX调用时,它100%有效。当我远程打电话时,大约20%的时间是正常的。

当它失败时,我得到以下错误:

The given key was not present in the dictionary.

意思是在全局字典对象中找不到票号。

在过去的几个月里,我已经实现了相当多的Lazy singleton,而且我从来没有遇到过这种情况。

我哪里做错了?

//Initital POST request, sent to the service with the string[]
public string Post([FromBody]string value)
{
    try
    {
        var urlList = new JavaScriptSerializer().Deserialize<List<string>>(value);
        var helper = new Helper();
        var random = helper.GenerateNumber(10);
        CacheDictionary<String, List<String>>.Instance.Add(random, urlList);
        return random;
    }
    catch (Exception ex)
    {
        return ex.Message;
    }
}
//Response, cut off where the error occurs
public async Task<HttpResponseMessage> Get(string id)
{
    try
    {
        var urlList = CacheDictionary<String, List<String>>.Instance[id];
    }
    catch (Exception ex)
    {
        var response = new HttpResponseMessage(HttpStatusCode.InternalServerError)
        {
            Content = new StringContent(ex.Message)
        };
        return response;
    }
}
//CacheDictionary in its Lazy Singleton form:
public class CacheDictionary<TKey, TValue>
{
    private Dictionary<TKey, TValue> dictionary;
    private Queue<TKey> keys;
    private int capacity;
    private static readonly Lazy<CacheDictionary<String, List<String>>> lazy =
        new Lazy<CacheDictionary<String, List<String>>>(() => new CacheDictionary<String, List<String>>(10000));
    public static CacheDictionary<String, List<String>> Instance { get { return lazy.Value; } }
    private CacheDictionary(int capacity)
    {
        this.keys = new Queue<TKey>(capacity);
        this.capacity = capacity;
        this.dictionary = new Dictionary<TKey, TValue>(capacity);
    }
    public void Add(TKey key, TValue value)
    {
        if (dictionary.Count == capacity)
        {
            var oldestKey = keys.Dequeue();
            dictionary.Remove(oldestKey);
        }
        dictionary.Add(key, value);
        keys.Enqueue(key);
    }
    public TValue this[TKey key]
    {
        get { return dictionary[key]; }
    }
}

更多错误详情

at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at ZipperUpper.Models.CacheDictionary`2.get_Item(TKey key)

全局对象的不一致持久性

我想你会发现这与你的全局字典的位置有关。例如,如果这是一个web farm,并且你的字典在Session中,你的应用程序的一个实例可以从另一个实例访问不同的Session,除非Session状态处理设置正确。在您的情况下,它位于云中,因此您需要以相同的方式为不同机器处理的相关请求和响应提供准备。因此,一个可以发送键,另一个可以接收AJAX重定向,但在其自己的"全局"数据中没有该键。