消息关闭
    暂无新消息!
如题,如何定义后台控制器的一个全局变量(用来存储某个类对象),并且保证线程安全(其他用户访问的时候获取不到当前用户操控的这个对象),我要保存这个对象的数据,测试了下声明为public 不行,两次ajax请求,第二次获取到是空的了?请问大牛们如何实现这个需求?

14个回答

︿ 2


sp1234  作为.net版块的大牛,基本上能看见他的身影。回答问题只给我们讲大致思路 然后自己动手去操作,这种回答方法对有些思考和动手能力强的有用,但对有些想直接知道答案的就有点无力了。 楼主还是要虚心点为好。理解楼主的心态
︿ 2
用ajax配合Asp.net的一般处理程序。可以成功。保证线程安全的话只要保证只有ajax访问你这个对象的数据。其他不能访问就行了。
︿ 1
在C#界,其实没有全局变量这个叫法

不过,C#里有一种类很特别,可以用它来作为全局变量使用,也就是传说中的静态类,这种类很特别的,不管你是声明它为public或者私有的,只要你某个角落的代码里有调用该类里的一个成员或者new它一个对象,它会第一时间执行构造函数一次,并且永远只执行这一次,绝不会执行第二次

所以,不管你有多少个人在访问你的程序,有多少个人调用了涉及到该类的代码,只要它之前的第一次已被破处了,那么后面的这些一切访问调用,永远都只能用它的地址指向副本(反正你要记住,内存里永远只分给它一点空间,谁爱访问就访问,不访问拉倒)

正是因为它不管被多少人请求使用,内存里就只有独一无二的一个它,所以,它就是大家一起共享的东东,这也就是为什么它能代替全局变量的原因所在了,它不属于某个人的,包括第一个破它处的人,也不能单独拥有它,它一旦生成,就注定是属于大众的,或者说是属于服务器上IIS里运行的某个网站程序的程序域里(每个软件运行都有自己的程序域的,比如你的QQ与酷狗音乐,它们有自己的域空间,轻易不能相互沟通的)。

然后说到访问类型public,这个你别想太多,这个单词是对于我们的代码而言的,不是指我们人类,比如类与类之间,程序集与程序集之间的访问权限,打个比方,你一个BLL程序集里两个类要相互访问,与两个BLL之间的类相互访问,这时候公共的,受保护的,私有的机制就有用了

其实微软官方自己就有自己的静态类了,比如 Application 和多年之前我用过的缓存类Cache,并且它们能像容器一样,装进你自己另外定义的类(其实我们也可以定义自己的容器类的,这里我不多说了,该要看的书还是要看多一些的)

说了这么多,好像过了头了,哈哈

好了,既然静态类能作为全局变量,那么,不用说别的,单只内存中它永远只有一个存在时,这一点,就注定它不是线程安全的,注定没有人能单独占用它,它注定是被大家共享的

那么,C#就使用另一个锁的机制,让它能被某个人私自占用一会的,等占用完了,还是要把它解锁出来给他人用的,至于C#里的锁机制,你可以去百度一下lock(锁)和unlock(解锁),这里我就不当教科书了

最后提醒一下ASP.NET的悲剧,无状态,不管你多牛B的变量机制,只要一段时间没人访问你的网站,IIS就会把你的网站给停了挂起,反正就是回收你这个程序里之前分配的那些变量占的内存,可见,什么鬼全局变量都被回收了,什么鬼共享数据还怎么找回?(说起这个,肯定好多人被session超时问题搞痛苦过)。

所以聪明的人是利用ASP.NET的机制的,比如Global.asax文件里有一个protected void Application_Start(object sender, EventArgs e)函数,它是程序开始运行时执行一次,在这里可以把之前存在数据库里的东东重新拿出来,就能够实现像继点上传的功能了(就是接着上次的数据)

当然,聪明的人也会利用protected void Application_End(object sender, EventArgs e)函数,在程序被关闭前(包括被IIS强制扶挂起),把一些数据保存到数据库或存到其它硬盘文件就可以了

近1年没来论坛了,今天抽空上来一下,一下子写了这么黑多字,看来我的表述能力还是不行哈,不够精简
︿ 1
这样的需求其实可以考虑的方法不是很多的。

Application、InProc Session、自己声明 static 实例,是一类方法。应用程序重启后就失效。

StateService Session,是一类方法,相关服务重启后失效。

写到文件、数据库,是一类方法,具有【持久化】的特征,是最可靠的方法,并且数据库有完善的锁设计,也就是说更容易做到【线程安全】。

你这个例子中,public 是访问修饰符,和是否【全局】没有关系,【全局】对应的关键字是【static】
︿ 1
最后web的解决办法是  发送ajax请求后将那个实例化的类序列化然后返回到前台,再次请求的时候把它post到后台,然后反序列化为类对象,然后再进行下一步操作。这样将它的状态就保存下了。 暂时这么解决吧。 
︿ 0
全局变量就是全局变量,你这个要求没法满足。因为违背最起码的道理。
︿ 0
很难办到。
因为如果声明static,那么的确可以保存这个信息。但是所有的用户都会覆盖这个static信息。
但如果只是public那么你也说了,每次进去都是一个新的对象。
所以,我觉得你还是存在session中
︿ 0
题主首先文字表达能力实在有限,描述不清自己碰到的问题;其次心态不好,不虚心。

我帮你换个问法:

在WEB应用程序中,一个用户在请求控制器时产生了一个数据(某个类的实例),使用什么方式来存储它(不考虑数据),才能使得该用户下次请求控制器时,还能使用这个数据?

答案是:使用会话变量,也就是Session。

顺便提一句:如果你全面地学习过asp.net的基础部门,那么当你想到这个需求时,你应该会很自然地想到这个答案,而不是去折腾什么“全局变量”。c#语言中没有全局变量这个概念。
︿ 0
你思考的逻辑不对,执意这样去做解决不了问题,就算是执意这样解决了问题,那也是垃圾程序