在开发“网站”的时候,我们引入了“内存数据库”的概念。其基本原理是,当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);
到这里为止,我们的解题就全部解决了。
阅读(796) | 评论(0) | 转发(0) |