asp.net中关于静态变量的生命周期和线程安全以及一些类中的定义静态变量的概念

public class StaticDictory
    {
      public static Dictionary<int, string> CataLog;
      public static Dictionary<int, string> RoleName;
      public int A;
      public StaticDictory()
      {
          this.A = 5;
      }
      public StaticDictory(int B)
      {
          this.A = B;
      }
      static  StaticDictory()
      {
          CataLog = new Dictionary<int, string>();
          CataLog.Add(1, "瑜伽部落");
          CataLog.Add(2, "自行车部落");
          CataLog.Add(3, "大学生部落");
          RoleName = new Dictionary<int, string>();
          RoleName.Add(1, "导师经销商");
          RoleName.Add(2, "加盟经销商");
          RoleName.Add(3, "金牌销售代表");
          RoleName.Add(4, "银牌销售代表");
          RoleName.Add(5, "战略合作伙伴");
          RoleName.Add(6, "加盟经销商");
          RoleName.Add(7, "练习者");
          RoleName.Add(8, "管理员");
          RoleName.Add(9, "超级管理员");
          RoleName.Add(10, "生产线管理员");
          RoleName.Add(11, "财务管理员");
          RoleName.Add(12, "总经理管理员");
          RoleName.Add(13, "总经理助理管理员");
          RoleName.Add(14, "销售协议结构");
          RoleName.Add(15, "明星销售代表");
          RoleName.Add(16, "普通会员");
          RoleName.Add(17, "普通会员");
          RoleName.Add(18, "大学生首领");
          RoleName.Add(19, "学生组织");
          RoleName.Add(20, "大学生销售代表");
      }
    }
 
在类中只能定义一个静态的构造函数,是在创建第一个类实例或任何静态成员被引用时,.NET将自动调用静态构造函数来初始化类,也就是说我们无法直接调用静态构造函数,也就无法控制什么时候执行静态构造函数了,他的生命周期下面有介绍。静态函数只能调用和初始化静态成员。实例化函数可以调用静态成员和实例化成员。同理静态函数不能调用实例化函数,实例化函数可以调用静态函数和实例化函数。
 
别的函数需要实例化,StaticDictory AA=new StaticDictory(6);实例话了对象,才可以调用实例化成员,类不写构造函数的话会有默认构造函数。
文章来自: 好喜爱学习网(http://www.haoxiai.net/) 网址:http://www.haoxiai.net/bianchengyuyan/aspnetbiancheng/82327.htmlasp.net中关于静态变量的生命周期和线程安全

本来我理解的静态变量的生命周期是

    void Application_Start开始

    void Application_End结束的,本来这就是对的

今天要做一个全局的应用,想确认一下,在网上一找,我的天,说什么的都有

大概分三种

1.Application_Start——Application_End

2.Session_Start——Session_End

3.类生命周期结束

我用4个机器做了一个测试发现静态变量值一直是不变的,并没有因为其它用户登录而被销毁,确认应该是Application级的

静态类在首次访问时会调用静态构造器创建类类型对象,类型对象的生存周期是整个应用程序域的生存周期,也就说被访问过的静态类,只有它所在的应用程序域被卸载时才会被卸载。

类的成员分为两类,静态成员(static member)和实例成员(instance member)。静态成员属于类,实例成员则属于对象,即类的实例。

    简单讨论一下在一个类中使用静态字段(static field)和静态方法(static method)是否会有线程安全问题。 

    我们在知道, 静态字段(static field)和静态方法(static method)的调用是通过类来调用。静态方法不对特定的实例操作,只能访问静态成员。实例方法可对特定的实例操作,既能访问静态成员,也能访问实例成员。

    那么,在多线程中使用静态方法是否有线程安全问题?这要看静态方法是是引起线程安全问题要看在静态方法中是否使用了静态成员。

    因为,在多线程中使用同一个静态方法时,每个线程使用各自的实例字段(instance field)的副本,而共享一个静态字段(static field)。所以说,如果该静态方法不去操作一个静态成员,只在方法内部使用实例字段(instance field),不会引起安全性问题。但是,如果该静态方法操作了一个静态字段,则需要静态方法中采用互斥访问的方式进行安全处理。
   
    举个简单的例子,我们使用的Console.WriteLine();中WriteLine()是Console.WriteLine类的静态方法。

     对于ASP.NET, 多个客户端访问服务器端, 这是一个多线程的例子.只要理解了原因,我们可以在三层架构中的数据访问层中放心使用静态方法(static method)来访问数据库.

静态方法如果没有使用静态变量,则没有线程安全问题。

为什么呢?因为静态方法内声明的变量,每个线程调用时,都会新创建一份,而不会共用一个存储单元。每个线程都会创建自己的一份,因此不会有线程安全问题

注意,静态变量,由于是在类加载时占用一个存储区,每个线程都是共用这个存储区的,所以如果在静态方法里使用了静态变量,这就会有线程安全问题!

FeedBack:
2009-05-24 22:55 | merry05[未注册用户]
今天也遇到这个问题,就利用google到你这儿了

但这样还有一个问题static变量为application级别的,那这个变量所存储的值能在多个用户之间共享吗?如果多个用户都想使用这个值,那如何做到互斥?

在Application中有个lock()的操作,而普通的static却没有!

 回复 引用   
#2楼[楼主]
2009-05-25 11:12 | 宏宇      
当然是共享的,就因为他是比较单一的共享,没有什么自己的方法,所以一般都用在经常用但是只读的字段
 回复 引用 查看   
2009-05-26 20:12 | merry05[未注册用户]
谢谢你的回复

经过这几天的查找,得知可以加了static mutex来实现互斥

 回复 引用   
2009-05-27 16:45 | siso[未注册用户]
请问下博主,Asp.net中,我在一自定义类 声明一静态变量
然后在Default的Button1中读取。

我是发布网站后在IIS试验的

当我把所有打开的浏览器窗口关闭后,再访问Default,仍然可访问到该静态变量,甚至把IIS停止再开始 ,仍然可以访问静态变量。
直到重启计算机才读不到静态变量。

我想了解的是Application_End到底什么时候才会执行。谢谢!

 回复 引用   
#5楼[楼主]
2009-05-28 14:00 | 宏宇      
1、Application_Start:这个事件被请求一次后,只要你不重新启动IIS以后就再也不出发了。(有时不然,有待讨论)
Application_BeginRequest:这个事件每次请求后都触发,即使在同一个浏览器中刷新也不例外。
Application_AuthenticateRequest:每次请求都被触发。
Session_Start:这个事件跟浏览器实例相关,每次打开一个新浏览器时被触发。
Application_EndRequest:跟BeginRequest时间一样,只是触发顺序不同。
Session_End:session过期或用户调用Session.Abandon()结束会话时触发。
Application_End:停止iis时在iis尚未被停止之前被触发。
Application.Error:提供一种在应用程序级处理错误的方式。所有错误都可以从页面“冒泡”到应用程序级,在这里面你可以将错误写入日志或转向其他页面。

 回复 引用 查看   
#6楼[楼主]
2009-05-28 14:02 | 宏宇      
Application_End停止iis或者IIs重启时触发和客户端没有关系
 回复 引用 查看   
2009-06-01 15:02 | siso[未注册用户]
谢谢回复,但还是有些不太明白

Application_End:停止iis时在iis尚未被停止之前被触发。
----------------------------------------------

IIS 的停止是指得停止服务还是在IIS管理器点那个停止就可以了?
我是在服务器的IIS管理器点那个四方形的停止的。

这时应该Application_End会触发吧,可是好像没有触发


-----------------------------------------
Application_End停止iis或者IIs重启时触发和客户端没有关系
-----------------------------------------
我想既然静态变量是保存在服务端的,而且上面您的文章有提到静态变量的结束周期是在Application_End触发时。

那么我想只要在服务器端停止IIS,那么我在客户端(读取服务器的生成)应该就访问不到该静态变量了,可是事实是仍然访问得到。谢谢!

 回复 引用   
#8楼[楼主]
2009-06-01 16:36 | 宏宇      
晕 ,你在客户端得到静态变量的时候,应用程序肯定是已经开启了,要不程序你也没办法访问
 回复 引用 查看   
#9楼[楼主]
2009-06-01 16:43 | 宏宇      
Application_End是指应用你这个程序结束时触发的,和IIS结束没有关系,只不过是IIS结束引起了你的应用程序结束
注:你在Application_End事件设断点,然后重启IIS服务,如果这个Web程序发布在IIS上,那么这个事件将被触发

 回复 引用 查看   
2009-06-02 13:59 | siso[未注册用户]
--引用--------------------------------------------------
宏宇: Application_End是指应用你这个程序结束时触发的,和IIS结束没有关系,只不过是IIS结束引起了你的应用程序结束
注:你在Application_End事件设断点,然后重启IIS服务,如果这个Web程序发布在IIS上,那么这个事件将被触发
--------------------------------------------------------


我的WEB是发布在IIS中了,假设我Default中原静态变量a值为10
Button1改变a的值为20, Button2读取并显示该变量。
即如果我点击button1后,再Button2,应该显示20
我想了解的是,在点击Button1之后,什么情况下,Button2仍然显示原来的值10。

跟据你上面的文章,如果我没有理解错的话应是该静态变量周期结束时。
而静态变量结束周期==Application_End==IIS重启

所以我IIS重启后,理论上重新打开浏览器,按Button2,应该显示的值为10,而不是20.但事实是IIS重启后,仍然显示20. 即静态变量周期仍没有结束。
所以…………
谢谢!



 回复 引用   
#11楼[楼主]
2009-06-03 11:22 | 宏宇      
public class Class1
{
public static string w;
public Class1()
{
//
// TODO: Add constructor logic here
//
}
}
<html xmlns="http://www.w3.org/1999/xhtml%22%3E
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
</div>
</form>
</body>
</html>

protected void Page_Load(object sender, EventArgs e)
{
string www = Class1.w;
}
protected void Button1_Click(object sender, EventArgs e)
{
Class1.w = "1";
}

流程:
1.运行程序string www=null
2.点击button,string www="1"
3.重启IIS
4.关闭当前页面(此时不要操作页面了,一操作就又启动了)
5.再启动程序(应用程序的内存空间重新创建)
6.string www=null

 回复 引用 查看   
2010-01-06 22:37 | ASTAR Coming Now      
在多线程应用场景里面,在静态方法中,如果不是用静态变量,那么操作应该是没有问题,这点可以确认。

那么,使用静态变量的方法呢?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
namespace Dottext.Framework.Providers
{
    /// <summary>
    /// Summary description for DTOProvider.
    /// </summary>
  
    public class DTOProvider
    {
        private DTOProvider(){}
  
        static DTOProvider()
        {
            DTOProviderConfiguration dtoPC = Config.Settings.BlogProviders.DTOProvider;
            idto = (IDTOProvider)dtoPC.Instance();
        }
  
        private static IDTOProvider idto = null;
        public static IDTOProvider Instance()
        {
            return idto;
        }
    }
}


上面代码可见
idto是一个静态变量。
我们会去使用idto的方法,假设idto的类定义有方法foo
要保证不出现访问冲突。
foo方法内都不能操作静态变量和成员变量?
(可以访问但不能写)

我的理解是否正确?

原文地址:https://www.cnblogs.com/scottpei/p/2365245.html