微软企业库缓存应用程序块不是线程安全的? [英] Microsoft Enterprise Library Caching Application Block not thread safe?

查看:181
本文介绍了微软企业库缓存应用程序块不是线程安全的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个超级简单的控制台应用程序来测试企业库缓存应用程序块,并且行为是令人费解。我希望我搞砸一件容易的设置来解决。我有5秒钟后,每个项目过期用于测试目的。

基本设置 - 每一秒挑一个介于0和2。如果缓存中已经没有它,把它放在那里 - 否则只是抓住它从缓存中做到这一点LOCK语句中,以确保线程安全。

的app.config:

 <结构>
  < configSections>
    <节名称=cachingConfigurationTYPE =Microsoft.P​​ractices.EnterpriseLibrary.Caching.Configuration.CacheManagerSettings,Microsoft.P​​ractices.EnterpriseLibrary.Caching,版本= 4.1.0.0,文化=中性公钥= 31bf3856ad364e35/>
  < / configSections>
  < cachingConfiguration defaultCacheManager =缓存管理器>
    < cacheManagers>
      <新增expirationPollFrequencyInSeconds =1maximumElementsInCacheBeforeScavenging =1000
      numberToRemoveWhenScavenging =10backingStoreName =null存储
      TYPE =Microsoft.P​​ractices.EnterpriseLibrary.Caching.CacheManager,Microsoft.P​​ractices.EnterpriseLibrary.Caching,版本= 4.1.0.0,文化=中性公钥= 31bf3856ad364e35
      NAME =缓存管理器/>
    < / cacheManagers>
    < backingStores>
      <新增encryptionProviderName =类型=Microsoft.P​​ractices.EnterpriseLibrary.Caching.BackingStoreImplementations.NullBackingStore,Microsoft.P​​ractices.EnterpriseLibrary.Caching,版本= 4.1.0.0,文化=中性公钥= 31bf3856ad364e35
      NAME =null存储/>
    < / backingStores>
  < / cachingConfiguration>
< /结构>
 

C#:

 使用系统;
使用System.Collections.Generic;
使用System.Linq的;
使用System.Text;
使用Microsoft.P​​ractices.EnterpriseLibrary.Common;
使用Microsoft.P​​ractices.EnterpriseLibrary.Caching;
使用Microsoft.P​​ractices.EnterpriseLibrary.Caching.Expirations;

命名空间ConsoleApplication1
{
    类节目
    {
        公共静态的ICacheManager缓存= CacheFactory.GetCacheManager(缓存管理器);
    静态无效的主要(字串[] args)
        {
            而(真)
            {
                System.Threading.Thread.Sleep(1000); //睡眠一秒钟。
                VAR键=新的随机()下(3)的ToString()。
                字符串值;
                锁定(高速缓存)
                {
                    如果(!cache.Contains(键))
                    {
                        cache.Add(密钥,密钥,CacheItemPriority.Normal,空,新SlidingTime(TimeSpan.FromSeconds(5)));
                    }
                    值=(字符串)cache.GetData(密钥);
                }
                Console.WriteLine({0}  - >{1}键,值);
                //如果(空==值)抛出新的异常();
            }
        }
    }
}
 

输出 - ?我怎样才能prevent从返回空值缓存

  2  - > '2'
1  - > '1'
2  - > '2'
0  - > '0'
2  - > '2'
0  - > '0'
1  - > ''
0  - > '0'
1  - > '1'
2  - > ''
0  - > '0'
2  - > '2'
0  - > '0'
1  - > ''
2  - > '2'
1  - > '1'
preSS任意键继续。 。 。
 

解决方案

我注意到,你似乎得到只要从该项目一直没有缓存回在previous 5循环迭代(即5秒)进行访问。难道这是关系到你的5秒到期时间?

这似乎不太可能,但也许你有一个竞争条件和物品掉出的缓存中包含检查和的GetData 检索。

试试这个变化,看看它是否有什么差别的输出:

 ,而(真)
{
    System.Threading.Thread.Sleep(1000);

    VAR键=新的随机()下(3)的ToString()。
    字符串值;

    锁定(高速缓存)
    {
        值=(字符串)cache.GetData(密钥);
        如果(价值== NULL)
        {
            =键值;
            cache.Add(键,值,CacheItemPriority.Normal,空,
                新SlidingTime(TimeSpan.FromSeconds(5)));
        }
    }
    Console.WriteLine({0}  - >{1}键,值);
}
 

I created a super simple console app to test out the Enterprise Library Caching Application Block, and the behavior is baffling. I'm hoping I screwed something that's easy to fix in the setup. I have each item expire after 5 seconds for testing purposes.

Basic setup -- "Every second pick a number between 0 and 2. If the cache doesn't already have it, put it in there -- otherwise just grab it from the cache. Do this inside a LOCK statement to ensure thread safety.

APP.CONFIG:

<configuration>
  <configSections>
    <section name="cachingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Caching.Configuration.CacheManagerSettings, Microsoft.Practices.EnterpriseLibrary.Caching, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  </configSections>
  <cachingConfiguration defaultCacheManager="Cache Manager">
    <cacheManagers>
      <add expirationPollFrequencyInSeconds="1" maximumElementsInCacheBeforeScavenging="1000"
      numberToRemoveWhenScavenging="10" backingStoreName="Null Storage"
      type="Microsoft.Practices.EnterpriseLibrary.Caching.CacheManager, Microsoft.Practices.EnterpriseLibrary.Caching, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
      name="Cache Manager" />
    </cacheManagers>
    <backingStores>
      <add encryptionProviderName="" type="Microsoft.Practices.EnterpriseLibrary.Caching.BackingStoreImplementations.NullBackingStore, Microsoft.Practices.EnterpriseLibrary.Caching, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
      name="Null Storage" />
    </backingStores>
  </cachingConfiguration>
</configuration>

C#:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Common;
using Microsoft.Practices.EnterpriseLibrary.Caching;
using Microsoft.Practices.EnterpriseLibrary.Caching.Expirations;

namespace ConsoleApplication1
{
    class Program
    {
        public static ICacheManager cache = CacheFactory.GetCacheManager("Cache Manager");
    static void Main(string[] args)
        {
            while (true)
            {
                System.Threading.Thread.Sleep(1000); // sleep for one second.
                var key = new Random().Next(3).ToString();
                string value;
                lock (cache)
                {
                    if (!cache.Contains(key))
                    {
                        cache.Add(key, key, CacheItemPriority.Normal, null, new SlidingTime(TimeSpan.FromSeconds(5)));
                    }
                    value = (string)cache.GetData(key);
                }
                Console.WriteLine("{0} --> '{1}'", key, value);
                //if (null == value) throw new Exception(); 
            }
        }
    }
}

OUTPUT -- How can I prevent the cache from returning nulls?

2 --> '2'
1 --> '1'
2 --> '2'
0 --> '0'
2 --> '2'
0 --> '0'
1 --> ''
0 --> '0'
1 --> '1'
2 --> ''
0 --> '0'
2 --> '2'
0 --> '0'
1 --> ''
2 --> '2'
1 --> '1'
Press any key to continue . . .

解决方案

I notice that you seem to be getting null back from the cache whenever that item hasn't been accessed during the previous 5 loop iterations (ie, 5 seconds). Could this be related to your 5 second expiry time?

It seems unlikely, but maybe you have a race condition and the items are dropping out of the cache between the Contains check and the GetData retrieval.

Try this change and see if it makes any difference to the output:

while (true)
{
    System.Threading.Thread.Sleep(1000);

    var key = new Random().Next(3).ToString();
    string value;

    lock (cache)
    {
        value = (string)cache.GetData(key);
        if (value == null)
        {
            value = key;
            cache.Add(key, value, CacheItemPriority.Normal, null,
                new SlidingTime(TimeSpan.FromSeconds(5)));
        }
    }
    Console.WriteLine("{0} --> '{1}'", key, value);
}

这篇关于微软企业库缓存应用程序块不是线程安全的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆