Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3471819
  • 博文数量: 1450
  • 博客积分: 11163
  • 博客等级: 上将
  • 技术积分: 11101
  • 用 户 组: 普通用户
  • 注册时间: 2005-07-25 14:40
文章分类

全部博文(1450)

文章存档

2017年(5)

2014年(2)

2013年(3)

2012年(35)

2011年(39)

2010年(88)

2009年(395)

2008年(382)

2007年(241)

2006年(246)

2005年(14)

分类: 系统运维

2007-12-14 09:11:58


    在 开发“网站”的时候,我们引入了“内存数据库”的概念。其基本原理是,当web服务器一启动的时候,就将数据库中的所有表全部导入到 Globle.asax中的Application[“dsDetailInfo”]中,它是一个web应用程序的全局变量。这样就可以大大增加用户的访 问速度,从而达到比较好的效果。
   但在开发的过程序中我们遇到了一个棘手的问题,就是不能使用自己编写的类直接调用在Globle.asax文件中定义的 Application对象。其原因是这样的,Application是Web应用中的一个全局变量,在整个的Web应用中,它都是惟一的。任何一个页面 都可以对其进行访问。而我们编写的类是通用类,它不属于一个具体的web应用还是窗口应用。也就是说,我们所编写的类既可以用在Web应用上,也可以用在 窗口应用上。
   这样就会出现一个问题,由于我们编写的类不是仅用于web应用的,所以web应用中的一些特性,如Application、 Session等web应用变量,在我们编写的类中当然也就体现不出来。即所谓的不允许直接调用。而现在我们又恰恰想使用web应用中的这些特性,这该怎 么办呢?
   可以不可以直接将Application对象直接在页面里转换后使用呢?答案是否定的。在一般的web应用中,当然可以采用这种方式,但如果我们这里也采用这种方式,那么又会出现另外一些问题,一是效率的问题,二是数据一致的问题。
    我们原本的思想是通过Application[“dsDetailInfo”]来实现一个内存数据库,如果采用上面的方法,这时就必须在每次页面 转换时再生成一个新dsDetailInfo。这个对象本身有好几十张表,数据量非常大,估计经过几次转换之后,整个系统就要崩溃了。
    第二点是,即使可以通过转换的方式实现,那么在做更新,删除,修改这些操作时,如何才能达到数据的一致性呢?举个例子,如第一个用户想将数据插 入到内存数据库中,而另一个用户也想将它自己的数据插入到内存数据库中。本来他们是想将他们的数据都插入到同一个内存数据库中,但实际的操作如何呢?实际 上他们插入的数据并没有真正放到同一个内存数据库中,而是分别入到了他们自己的那一份拷贝中去了。所以说这种做法是行不通的。
   通过研究,我发现可以使用HttpContext和HttpApplication这两个类来完成我们想要做的事情。看如下代码:

第一步:public class AppTest:System.Web.HttpApplication

首先,我们要使我们的类继承System.Web.HttpApplication这个类,这是因为只有继承了这个类之后,我们才可以对 Application变量进行操作。声明的格式如上所示。
第二点就是要在每个类的前面加上:

//生命一个静态变最用于存放web应用中惟一的上下文
第二步: private static HttpContext context;

这条语句。这样我们就可以得到web应用上下文的一份引用(因为我们要用的是同一份引用,所以这里使用的是静态变量。),这时我们就可以在我们的类中对这个上下文进行各种操作了。

举个例子,我在globle.asax定义了如下Application变量:

//声明的Application变量
         第三步:Application["myApp"] = "hello";


现在就以这个为目标,来对它进行操作,声明一个类如下:
public class AppTest:System.Web.HttpApplication
{
      //生命一个静态变最用于存放web应用中惟一的上下文
      private static HttpContext context;

      public AppTest()
      {}
      
      //可以实例做时直接将上下文传入
      public AppTest(HttpContext ctxt)
      {  context = ctxt;    }
      
      //也可以产生单一模式
      public static void Instance(HttpContext ctxt)
      {   context = ctxt;   }
      
      //得到Application的值
      public static string GetMessage()
      {
         try
         {
            if((context.Application["myApp"])!=null)
            {
               return ((string)context.Application["myApp"]);
            }
         
            return null;
         }
         catch(Exception ex){return null;}
         
      }
      //设置Application的值
      public static void SetApplicationVal(string val)
      {
         try
         {
            //用于将用户输入的值修改到Application中
            context.Application["myApp"] = val;
         }
         catch(Exception ex){}
      }

   }
这个类主要有两个方法,一个是从Application中得到其中的值,另一个是将数据放到Application中去。我们只要验证在多个用户 下操作时,当进行读操作进时,读到的都是同样的结果。而当写操作时,一个用户将其改变,而另一个用户能够得到其改变的值即可。通过验证,这种方法是完全正 确的。
最后我们需要确认一下,在什么时候对类进行实例化,什么时候使用比较好呢?一般情况下,最好的实例化的地方是在Globle.asax文件中,如下所示:

//         方式 一
////         AppTest at = new AppTest();
////         at.Instance(this.Context);

         //方式 二
         //将本web应用的上下文传到类中
         AppTest.Instance(this.Context);

那我们又应在什么时候调用,又以何种方式调用呢?只要在你需要函数的时候,以 类名.方法这种方法就行了,这是最好办法。看一下例子中的代码:
object val= Request["app"];

            //如果val不为空或“”,就将它赋值给Application
            if(val==null || ((string)val).Length==0)
               val = "abc";
            else
               AppTest.SetApplicationVal((string)val);

到这里为止,我们的解题就全部解决了。
阅读(650) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~