全局对象的持久性不一致

时间:2014-08-19 21:48:25

标签: c# singleton global-variables

我正在开发Cloud-Hosted ZipFile创建服务。

这是一个跨源WebApi2服务,用于从无法托管任何服务器端代码的文件系统提供ZipFiles。

基本操作如下:

  • 用户发出与string[]个与文件位置相关的网址的POST请求
  • WebApi将数组读入内存,并创建一个票号
  • WebApi将票号返回给用户
  • AJAX回调然后将用户重定向到附加了票号的网址,这将返回HttpResponseMessage
  • 中的zip文件

为了处理故障单系统,我的设计方法是设置一个全局字典,将随机生成的10位数字与List<String>值配对,字典与Queue配对一次存储10,000个条目。 (Reference here

部分原因是WebApi不支持Cache

当我在本地进行AJAX调用时,它会100%有效地工作。当我远程拨打电话时,它的工作时间约占20%。

当它失败时,这就是我得到的错误:

The given key was not present in the dictionary.

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

在过去的几个月里,我实施了不少懒惰单身人士,我从未遇到过这种情况。

我哪里出错了?

//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)

1 个答案:

答案 0 :(得分:2)

我认为您会发现它与您查找全局词典的位置有关。例如,如果这是一个Web场,并且您的字典在Session中,则应用程序的一个实例可以从另一个实例访问另一个Session,除非正确设置了Session状态处理。在您的情况下,它位于云中,因此您需要以相同的方式为不同计算机处理的相关请求和响应进行配置。因此,可以发出密钥,另一个可以接收AJAX重定向,但没有自己的密钥&#34;全局&#34;数据。