需求:最近在用c#写一个收发数据的软件,收到数据(xml文件表示,一个XML文件,就是一类数据)后,解析,根据数据的头,进行不同的处理。
 情况:处理收数据,现在我为每类数据定义了一个类,然后写了一个分析函数,通过判断XML文件头节点,将数据放到了相应类的对象。
 问题:我现在要读取数据,进行处理,在界面上显示,我是不是该写个缓存,缓存读取的类对象,然后再处理?怎么写呢?C#数据缓冲机制

解决方案 »

  1.   

    /// <summary>
    ///Test2 的摘要说明
    /// </summary>
    public class Test2 : IEnumerable
    {
    delegate void EventSaveCache(object key, object value);private MappingContainer mContainer;/// <summary>
    /// 获取或设置当前缓存对象所在的关系映象容器
    /// </summary>
    public MappingContainer Container
    {
    get {
    return mContainer;
    }
    set {
    mContainer = value;
    }
    }/// <summary>
    /// 构造缓存对象
    /// </summary>
    public Test2()
    {
    // // TODO: 在此处添加构造函数逻辑 //
    }/// <summary>
    /// 用于缓存数据的Hashtable
    /// </summary>
    protected System.Collections.Hashtable _Cache = new System.Collections.Hashtable();protected Object _LockObj = new object();/// <summary>
    /// 获取指定键值的对象
    /// </summary>
    /// <param name="key">键值</param>
    /// <returns>object</returns>
    public virtual object GetObject(object key)
    {
    if (_Cache.ContainsKey(key)) return _Cache[key];
    return null;
    }/// <summary>
    /// 把对象按指定的键值保存到缓存中
    /// </summary>
    /// <param name="key">键值</param>
    /// <param name="value">保存的对象</param>
    public void SaveCaech(object key, object value)
    {
    EventSaveCache save = new EventSaveCache(SetCache);
    IAsyncResult ar = save.BeginInvoke(key, value, new System.AsyncCallback(Results), null);
    }private void Results(IAsyncResult ar)
    {
    EventSaveCache fd = (EventSaveCache)((AsyncResult)ar).AsyncDelegate;
    fd.EndInvoke(ar);
    }/// <summary>
    /// 把对象按指定的键值保存到缓存中
    /// </summary>
    /// <param name="key">键值</param>
    /// <param name="value">保存的对象</param>
    protected virtual void SetCache(object key, object value)
    {
    lock (_LockObj) {
    if (!_Cache.ContainsKey(key))
    _Cache.Add(key, value);
    }
    }public int Count
    {
    get {
    return _Cache.Count;
    }
    }/// <summary>
    /// 在缓存中删除指定键值的对象
    /// </summary>
    /// <param name="key">键值</param>
    public virtual void DelObject(object key)
    {
    lock (_Cache.SyncRoot) {
    _Cache.Remove(key);
    }
    }/// <summary>
    /// 清除缓存中所有对象
    /// </summary>
    public virtual void Clear() {
    lock (_Cache.SyncRoot) {
    _Cache.Clear();
    }
    }
    }/// <summary>
    ///针对一条记录操作命令的缓存类
    /// </summary>
    public class CachePersistentCommand : Test2
    {
    /// <summary>
    /// 把记录操作命令缓存到内存中
    /// </summary>
    /// <param name="key">标识</param>
    /// <param name="value">值</param>
    protected override void SetCache(object key, object value)
    {
    lock( _LockObj ) {
    int count=0;
    if( Container.Config.CommandsCache.ContainsKey( key ) )
    count=(int) Container.Config.CommandsCache[key];
    System.Collections.IList _list;
    //如果缓存中已经存在这种命令的列表 
    if( _Cache.ContainsKey( key ) ) 
    {
    _list = ( System.Collections.IList )_Cache[key];
    if(count >0 )//命令的缓存总数
    {
    if( _list.Count < count )//缓存数据量少于缓存总数
    _list.Add( value );
    }
    else {
    if( _list.Count < Container.Config.CommandBuffer )//缓存数小于组件的默认列表
    _list.Add( value );
    }
    }
    else//如果不存在列表 
    {
    if( count >0 || Container.Config.CommandBuffer >0 )//如果组件允许对象缓存
    {
    _list = new System.Collections.ArrayList( );
    _list.Add( value );
    _Cache.Add( key,_list );
    }
    }
    }
    }/// <summary>
    /// 从缓存中获取相关命令对象
    /// </summary>
    /// <param name="key">标识</param>
    /// <returns>IPersistentCommand</returns>
    public override object GetObject(object key)
    {
    if (_Cache.Contains(key))//如果命令存在缓冲中 
    {
    foreach (IPersistentCommand cmd in (System.Collections.IList)_Cache[key])
    {
    if (!cmd.State)//命令是否可以过行锁定
    if (cmd.Lock())//命令锁定
    return cmd;
    }
    }
    return null;
    }}
      

  2.   

     没必要用缓存吧,缓存那是一些访问量很大的网页才用的。如果你一定要缓存,你把它设置为static的就好了,他就自动的在内存中了。下次直接使用便可
      

  3.   

    参考下下面两篇博客的介绍:
    http://www.cnblogs.com/lj821022/archive/2007/04/25/726704.html
    http://www.cnblogs.com/legoras/articles/813526.html
      

  4.   

    比如说,收到xml数据,然后返回一个分析结果,你可能这样设计其功能接口public AType Analysis(string xml)
    {
        ........
        return result;

    在重复测试至少10遍(输入数据都不一样)证明它是正确的以后,你可以修改为public AType Analysis(string xml)
    {
        string key= Convert.ToBase64String(计算md5值(Encoding.Unicode.GetBytes(xml)));
        var cache=(Cache)HttpRuntime.Cache;
        var result=(AType)cache[key];
        if(cache[key]==null)
        {
            ........
            cache.Insert(key, result);    //以后还应该重视第三个和第四个参数上的缓存依赖项
         }
        return result;

    套用这样的模式,就可以进行数据缓冲。当.net进程发觉物理内存不够用,或者数据被保存了n久没有被使用过,或者你自己设置的各种缓存依赖项通知它时,缓存的单元result会自动清空。能够自动收缩缓存内容的,自动把脏数据清除掉的,才叫做缓存。
      

  5.   

    HttpRuntime.Cache返回Cache类型对象。虽然这个代码是建立在System.Web空间下,但是在wpf桌面、在你的windows service工程等下面都可以使用,不是只能用在asp.net中的。
      

  6.   

    爆各种雷人的设计模式名词儿,这在.net开发者中其实很少有人这样。你可以直截了当地说出很具体、没有歧义、从需求出发的设计技术思路,而不需要雷人的设计模式名词儿。
      

  7.   

    当.net进程发觉物理内存不够用,或者数据被保存了n久没有被使用过,或者你自己设置的各种缓存依赖项通知它时,缓存的单元result会自动清空。能够自动收缩缓存内容的,自动把脏数据清除掉的,才叫做缓存。你的意思是,分析xml文件,将每一个文件都存放到缓存区CASHE中。我用的时候取,那我怎么知道得到我想要的文件呢?俺也是刚学,各种机制不懂啊,以前用c++写过一个分析文件,将文件中的一个标志类型,以及内容存放在自己设计的结构体中,每得到一个结构体,就放到缓冲队列(自己写的)中,取得时候,再分析标志,获得其内容。
    因为在写缓冲队列的时候还要控制读写互斥,挺麻烦的。用到这个程序里面,应该能用。不知道有没有类似的这种机制?简单易实现的。