大部分人用的存取到硬盘我觉得这个效率并不好,况且。NET本身就有SESSION那么为什么不能用SESSION

解决方案 »

  1.   


    第一,服务器的关键就是很低的硬件配置可以给上千人使用。因而,只有瞬间之中的状态数据才在内存中驻留。如果你放入Session,服务器的用户承载能力是少下降100倍。第二,如果做过商品化网站应用都知道,Session是会自己“消失”的。网站服务器是什么概念?很简单,当我们浏览这个页面的时候,可能csdn服务器已经重新启动了,但是我们的下一个操作根本不受影响,这就是互联网上的应用的可靠性。如果依赖于Session、Application,那么就相当于把缓存当作可靠存储,基本的应用逻辑问题还没有解决。
      

  2.   

    我这不是瞬间的我这可以保存历史的VIEWSTATE可以设置回滚次数
      

  3.   

    关于SESSION丢失的问题我觉得是配置的问题.这个影响应该不大.而且也不是百分百丢呀
      

  4.   

    所以,不管是Session好、Cache也好,反正你的可靠数据必须同时写入硬盘的。你可以异步写,读取数据是可以先从内存查找。但是,如果忘记了写入硬盘,就不是效率高低这种概念了,而是完全没有可行性保证的。另外,我看到你“写死了”_objVIEWSTATE 这个key值。难道你没有遇到过会话中有多个请求的情况吗?例如一个页面中有下载图片而这个图片是使用一个aspx下载的、有Frame、有弹出页面、有多窗口(例如用户按 Ctrl+N)进行并行操作,等等情况。页面状态就是页面状态,用一个会话中的全局变量来保存页面范围的局部数据,这类编码是“三氯氰胺”一样的东西。
      

  5.   

    另外,我看到你“写死了”_objVIEWSTATE 这个key值。难道你没有遇到过会话中有多个请求的情况吗?例如一个页面中有下载图片而这个图片是使用一个aspx下载的、有Frame、有弹出页面、有多窗口(例如用户按 Ctrl+N)进行并行操作,等等情况。页面状态就是页面状态,用一个会话中的全局变量来保存页面范围的局部数据,这类编码是“三氯氰胺”一样的东西。
    我不明天这句话是啥意思
      

  6.   


    后半句话就不去评说了。单这前半句,请怎么配置能保证商品化的web服务器上的web应用程序不会被iis重启?!
      

  7.   

    咦你不知道这个?.NET的SESSION可以存到其他的机器上呀!
      

  8.   

    或者位于W3WP进程外.不过我也没有很深入的研究过MS说可以
      

  9.   

    实际上,web应用程序被iis重启大多数时候都是对网站非常有好处的。例如应用程序有故障,甚至内存使用泄漏,当“警报响起”的时候iis就会自我维护应用程序。许多服务器都要对各个网站设置不同的:占用CPU时间、内存使用、累计连接数限制,等等限制,对网站区别对待。“通过配置”去避免“Session丢失”是一种很不明智的行为。编程者如果只是在自己的电脑上写点小程序,很容易完全忽视Web服务器(特别是生产环境)的特点。至于Session集合key的“冲突”,我其实不用解释,只是告诉你的程序稍微复杂一点,开发的页面稍微多一点,编程稍微自由一点,一旦上线,这种“冲突”非常频繁,这也是你在自己的电脑上自己随便操作两三下所模拟不出来的并发使用情况。asp.net对所有页面请求的处理都是并发的。开发时,要对生产环境并发使用时出现问题要预先作为设计基础考虑进去,这往往影响了程序整个编程方式。
      

  10.   

    不懂lz这的意思我还没有用到过
    请大侠指点下“去掉ASP。NET页面中的VIEWSTATE非存硬盘方法”是什么意思
    有什么好处  怎么个用法啊?
    谢谢
      

  11.   


    我觉得这就有点狡辩了吧。你知道基于状态服务器或者SQL数据库的保存都要序列化和反序列化吗?请问你这个程序是否在“将Session保存到其它机器上去”的环境下做过一定量的测试?能够稍微描述一下进行这个测试的部署和开发你遇到了哪些入门书上所没有讲明的要点?例如我就讲出了“序列化反序列化”,但是我不告诉你何时、如何序列化,因为你用不到,你没有实际去做到那里。
      

  12.   

    <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTEzNDIxNDI1NjgPZBYCAgMPZBYiAgEPZBYCAgEPDxYCHgRUZXh0BTUyMDA45bm0OeaciDE55pelIOaYn+acn+S6lCDmiIrlrZAg6byg5bm0IOWFq+aciOW7v+WNgWRkAgMPZBYKAgMPDxYCHghJbWFnZVVybAUVfi9pbWFnZXMvaW5kZXgvc28uZ2lmZGQCBw8PFgIfAQUVfi9pbWFnZXMvaW5kZXgvc28uZ2lmZGQCCw8PFgIfAQUVfi9pbWFnZXMvaW5kZXgvc28uZ2lmZGQCDw8QDxYGHg1EYXRhVGV4dEZpZWxkBQVUaXRsZR4ORGF0YVZhbHVlRmllbGQFBFBLSUQeC18hRGF0YUJvdW5kZ2QQFRcNLS3or7fpgInmi6ktLQzljJblt6XmlrDpl7sM6KGM5oOF5Lit5b+DDOi0oue7j+WvvOivuwzkv4PplIDkv6Hmga8M6LS45piT5YiG5p6QDOS8geS4muaWh+WMlgzkuJPpopjmiqXlkYoM5pS/562W5qCH5YeGDOS8geS4muS6uueJqQfmnIkg5py6B+aXoCDmnLoH5aGRIOaWmQbmqaHog7YH6IO9IOa6kAbnsr7nu4YP6KGo6Z2i5rS75oCn5YmCDOafk+aWmeminOaWmQzlsZXkvJrkv6Hmga8QwqDCoOWxleS8muaWsOmXuxDCoMKg5bGV5Lya6aKE5ZGKEMKgwqDlsZXppobpo47ph4cQwqDCoOWxleS8muWbnumhvhUXAAIxNwIxOAIxOQIyNQIyNgIzMQIyOQIzNgIzNwIzOAIzOQI0MAI0MQI0MgI0MwI0NAI0NQIyNwIyOAIzMAIzMgIzMxQrAxdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2RkAhEPDxYCHwEFFX4vaW1hZ2VzL2luZGV4L3NvLmdpZmRkAgcPZBYCZg88KwAJAQAPFgYeDVJlcGVhdENvbHVtbnMCAh4IRGF0YUtleXMWAB4LXyFJdGVtQ291bnQCCmQWFGYPZBYCAgEPDxYCHgtOYXZpZ2F0ZVVybAUVaHR0cDovL3d3dy5oZHpkc2IuY29tZBYCZg8VAQzmlrDkuaHlro/ovr5kAgEPZBYCAgEPDxYCHwhlZBYCZg8VAQznqbrlub/lkYrkvY1kAgIPZBYCAgEPDxYCHwhlZBYCZg8VAQznqbrlub/lkYrkvY1kAgMPZBYCAgEPDxYCHwhlZBYCZg8VAQznqbrlub/lkYrkvY1kAgQPZBYCAgEPDxYCHwhlZBYCZg8VAQznqbrlub/lkYrkvY1kAgUPZBYCAgEPDxYCHwhlZBYCZg8VAQznqbrlub/lkYrkvY1kAgYPZBYCAgEPDxYCHwhlZBYCZg8VAQznqbrlub/lkYrkvY1kAgcPZBYCAgEPDxYCHwhlZBYCZg8VAQznqbrlub/lkYrkvY1kAggPZBYCAgEPDxYCHwhlZBYCZg8VAQznqbrlub/>
    就是去掉这玩意
      

  13.   

    当你真的明了InProc以外的状态管理方式是序列化/反序列化的,你此时就不惧怕通过一量行代码把序列化的字符串异步写入自己管理的硬盘了,因为这种方式比写入“其它机器”不但高效(你可能想不到),而且无需求助于“别的机器”,无需开启额外的服务。你不去计算“存到其他机器上”这个动作的时间、控件、安全性,更不能用来说他可以直接支持你的在本机内存中保存ViewState的代码。
      

  14.   

    <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTEzNDIxNDI1NjgPZBYCAgMPZBYiAgEPZBYCAgEPDxYCHgRUZXh0BTUyMDA45bm0OeaciDE55pelIOaYn+acn+S6lCDmiIrlrZAg6byg5bm0IOWFq+aciOW7v+WNgWRkAgMPZBYKAgMPDxYCHghJbWFnZVVybAUVfi9pbWFnZXMvaW5kZXgvc28uZ2lmZGQCBw8PFgIfAQUVfi9pbWFnZXMvaW5kZXgvc28uZ2lmZGQCCw8PFgIfAQUVfi9pbWFnZXMvaW5kZXgvc28uZ2lmZGQCDw8QDxYGHg1EYXRhVGV4dEZpZWxkBQVUaXRsZR4ORGF0YVZhbHVlRmllbGQFBFBLSUQeC18hRGF0YUJvdW5kZ2QQFRcNLS3or7fpgInmi6ktLQzljJblt6XmlrDpl7sM6KGM5oOF5Lit5b+DDOi0oue7j+WvvOivuwzkv4PplIDkv6Hmga8M6LS45piT5YiG5p6QDOS8geS4muaWh+WMlgzkuJPpopjmiqXlkYoM5pS/562W5qCH5YeGDOS8geS4muS6uueJqQfmnIkg5py6B+aXoCDmnLoH5aGRIOaWmQbmqaHog7YH6IO9IOa6kAbnsr7nu4YP6KGo6Z2i5rS75oCn5YmCDOafk+aWmeminOaWmQzlsZXkvJrkv6Hmga8QwqDCoOWxleS8muaWsOmXuxDCoMKg5bGV5Lya6aKE5ZGKEMKgwqDlsZXppobpo47ph4cQwqDCoOWxleS8muWbnumhvhUXAAIxNwIxOAIxOQIyNQIyNgIzMQIyOQIzNgIzNwIzOAIzOQI0MAI0MQI0MgI0MwI0NAI0NQIyNwIyOAIzMAIzMgIzMxQrAxdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2RkAhEPDxYCHwEFFX4vaW1hZ2VzL2luZGV4L3NvLmdpZmRkAgcPZBYCZg88KwAJAQAPFgYeDVJlcGVhdENvbHVtbnMCAh4IRGF0YUtleXMWAB4LXyFJdGVtQ291bnQCCmQWFGYPZBYCAgEPDxYCHgtOYXZpZ2F0ZVVybAUVaHR0cDovL3d3dy5oZHpkc2IuY29tZBYCZg8VAQzmlrDkuaHlro/ovr5kAgEPZBYCAgEPDxYCHwhlZBYCZg8VAQznqbrlub/lkYrkvY1kAgIPZBYCAgEPDxYCHwhlZBYCZg8VAQznqbrlub/lkYrkvY1kAgMPZBYCAgEPDxYCHwhlZBYCZg8VAQznqbrlub/lkYrkvY1kAgQPZBYCAgEPDxYCHwhlZBYCZg8VAQznqbrlub/lkYrkvY1kAgUPZBYCAgEPDxYCHwhlZBYCZg8VAQznqbrlub/lkYrkvY1kAgYPZBYCAgEPDxYCHwhlZBYCZg8VAQznqbrlub/lkYrkvY1kAgcPZBYCAgEPDxYCHwhlZBYCZg8VAQznqbrlub/lkYrkvY1kAggPZBYCAgEPDxYCHwhlZBYCZg8VAQznqbrlub/> 
    去掉这玩意
      

  15.   

    最简单的方法就是不要用服务器控件.这样又高效又没有垃圾代码.既然PHP和JSP都可以做得到,那.NET也可以做得到,不用服务器控件真的很好.
      

  16.   


    不论你是否序列化反序列化,当Session保存到“外部机器上”(如你所说)的时候需要再一次序列化反序列化,我是这个意思!我是提醒你注意为什么会“再一次”序列化、反序列化。你宁可把它序列化然后保存到“外部机器上”,而不愿“保存在硬盘上”,因此我觉得很奇怪的思路,希望你说明为什么保存到外部机器上比保存在本地好。也许你会说:我只是说“有可能”啊?!我并没有认真说必须保存到外部机器上啊!我知道保存在外部机器上相比本地机器又慢又不可靠的!那么这就又绕回来了。我说的是谁都知道所谓的“Session丢失”并不是一种新鲜玩意,你为什么又不考虑可靠地保存在本地,又不考虑可靠地保存在外部机器呢?!
      

  17.   


    我其实只是不想离开你的程序本身。我指出你没有考虑到Session的所谓普遍地在生产服务器上易丢失问题,你就立刻转移说“你不知道Session可以保存到外部机器吗?”。实际上,序列化之后保存到外部机器上难道比异步写到本地磁盘“这个效率并不好”?我是因为觉得你只是勉强找一个说法,你自己想一想也会知道答案,所以我不用去分析什么。
      

  18.   

    说白了,就是一点我揪住不放的:你不明确指出ViewState必须可靠地保存起来,以至于web应用程序重启时状态不丢失。你一开始否定需要保存在本地磁盘,那么请问你是要说明Session只有在“保存在外部机器”时你的程序才应该使用吗?如果是这样,那么我也算达到了目的,帮你说明了一个关键的实践问题,免得贻害那些在单机上个人写点小程序的人(他们写的东西从来没有拿到正式的生产环境服务器上使用过)。至于我说的“保存到外部机器上”要比异步保存在本地磁盘低效、不可靠,以及你对Session的key的写法会造成并发使用时产生逻辑错误(状态张冠李戴),是次要的,两点小毛病而已。
      

  19.   

    每一个东西都有一个东西的首要的“测试用例”。对于ViewState这种东西,你就要在两次页面访问之间,真的就把iis停掉,然后再启动,然后再看后一个访问是否好发无损。因为iis生产环境本来就是这样时不时地自我维护的。(你在自己的开发用的电脑上几乎遇不到这种情况)实际上,Session、Appilciation可以从来不用(仔细想一下),但是ViewState则是控件都要用的(他们从来不用Session、Application),所以,ViewState现在就是可靠的。经过你一改造,它变成不可靠的了,会随着应用重启而丢失,这就把ViewState的基础摧毁了。而你要求都要使用“外部服务器来保存Session”则会反而让你的程序变得更难以使用。我只是提醒你,asp.net的默认InProc模式下的Session是时有时无,你不要写一个程序以它不会消失为假设。
      

  20.   


    是呀,清楚地表明如何保持ViewState的持久化策略,如果借助于外部服务器也要清楚地表明必须以使用外部服务器为前提,程序就完整了。
      

  21.   

    实在是晕啊!
    不是说必要的时候禁用viewstate就可以了吗?
    其实我还是不清楚viewstate的作用。
      

  22.   

    public class SqlPageAdapter : PageAdapter
    { #region Methods /// <summary>
    /// Gets the Persister for SQL Server.
    /// </summary>
    /// <returns>
    /// An SqlPageStatePersister.
    /// </returns>
    public override PageStatePersister GetStatePersister()
    {
    SqlPageStatePersister persister = new SqlPageStatePersister(this.Page); return persister;
    }  #endregion Methods }
    public class SqlPageStatePersister : PageStatePersister
    { #region Fields private const string _hiddenFieldID = "__VIEWSTATEKEY";  #endregion Fields #region Constructors /// <summary>
    /// Initializes a new instance of the SqlPageStatePersister class.
    /// </summary>
    /// <param name="page">
    /// The page that provides the state to persist.
    /// </param>
    public SqlPageStatePersister(Page page) : base(page)
    {
    }  #endregion Constructors #region Properties /// <summary>
    /// Gets the connection string to the database that provides stored state.
    /// </summary>
    public string ConnectionString
    {
    get
    {
    string connectionString = null; ConnectionStringSettings settings =
    ConfigurationManager.ConnectionStrings["SqlPageStatePersisterConnectionString"]; if (settings != null)
    {
    connectionString = settings.ConnectionString;
    } return connectionString;
    }
    }  #endregion Properties #region Methods /// <summary>
    /// Loads state from SQL Server.
    /// </summary>
    public override void Load()
    {
    string key = this.Page.Request.Form[_hiddenFieldID]; if (!string.IsNullOrEmpty(key))
    {
    using (SqlConnection connection = new SqlConnection(this.ConnectionString))
    {
    SqlCommand command = new SqlCommand("GetWebClientPageState", connection);
    command.CommandType = System.Data.CommandType.StoredProcedure; command.Parameters.Add("@StateKey", System.Data.SqlDbType.UniqueIdentifier);
    command.Parameters["@StateKey"].Value = new Guid(key); connection.Open(); object rawState = command.ExecuteScalar(); connection.Close(); if ((rawState != null) && (rawState != DBNull.Value))
    {
    string stateText = Convert.ToString(rawState); Pair statePair = this.StateFormatter.Deserialize(stateText) as Pair; if (statePair != null)
    {
    this.ViewState = statePair.First;
    this.ControlState = statePair.Second;
    }
    }
    }
    }
    } /// <summary>
    /// Saves state to SQL Server.
    /// </summary>
    public override void Save()
    {
    if ((this.ViewState != null) || (this.ControlState != null))
    {
    Guid stateKey = Guid.NewGuid();
    string key = this.Page.Request.Form[_hiddenFieldID]; if (!string.IsNullOrEmpty(key))
    {
    stateKey = new Guid(key);
    }

    Pair statePair = new Pair(this.ViewState, this.ControlState); string stateText = this.StateFormatter.Serialize(statePair); using (SqlConnection connection = new SqlConnection(this.ConnectionString))
    {
    SqlCommand command = new SqlCommand("SetWebClientPageState", connection);
    command.CommandType = System.Data.CommandType.StoredProcedure; command.Parameters.Add("@StateKey", System.Data.SqlDbType.UniqueIdentifier);
    command.Parameters["@StateKey"].Value = stateKey; command.Parameters.Add("@State", System.Data.SqlDbType.Text);
    command.Parameters["@State"].Value = stateText; connection.Open(); command.ExecuteNonQuery(); connection.Close();
    } this.Page.ClientScript.RegisterHiddenField(_hiddenFieldID, stateKey.ToString());
    }
    }  #endregion Methods }
      

  23.   

    IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE ID = OBJECT_ID(N'WebClientPageState') AND XType = 'U')
    BEGINPRINT 'Creating Table WebClientPageState'CREATE TABLE WebClientPageState
    (
    Id BIGINT IDENTITY(1, 1) NOT NULL,
    StateKey UNIQUEIDENTIFIER NOT NULL,
    State TEXT NULL,
    DateSaved DATETIME NOT NULL DEFAULT (getdate())
    )CREATE INDEX IX_PageStateStateKey
    ON WebClientPageState(StateKey)CREATE INDEX IX_PageStateDateSaved
    ON WebClientPageState(DateSaved)

    ENDGOIF EXISTS (SELECT * FROM dbo.sysobjects WHERE ID = OBJECT_ID(N'SetWebClientPageState') AND XType = 'P')
    BEGIN
    PRINT 'Dropping Procedure SetWebClientPageState' DROP PROCEDURE SetWebClientPageState
    END
    GOPRINT 'Creating Procedure SetWebClientPageState'
    GOCREATE PROCEDURE SetWebClientPageState
    @StateKey UNIQUEIDENTIFIER,
    @State TEXT
    ASIF EXISTS (SELECT 1 FROM WebClientPageState WHERE StateKey = @StateKey)
    BEGIN
    UPDATE WebClientPageState
    SET State = @State,
    DateSaved = GETDATE()
    WHERE StateKey = @StateKey
    END
    ELSE
    BEGIN
    INSERT INTO WebClientPageState 
    (
    StateKey, 
    State, 
    DateSaved
    )
    VALUES 
    (
    @StateKey, 
    @State, 
    GETDATE()
    )
    ENDGO
    IF EXISTS (SELECT * FROM dbo.sysobjects WHERE ID = OBJECT_ID(N'RemoveExpiredWebClientPageState') AND XType = 'P')
    BEGIN
    PRINT 'Dropping Procedure RemoveExpiredWebClientPageState' DROP PROCEDURE RemoveExpiredWebClientPageState
    END
    GOPRINT 'Creating Procedure RemoveExpiredWebClientPageState'
    GOCREATE PROCEDURE RemoveExpiredWebClientPageState
    ASDECLARE @ExpirationMinutes INT
    DECLARE @ElapsedDate DATETIMESET @ExpirationMinutes = 60SET @ElapsedDate = DATEADD(minute, @ExpirationMinutes * -1, GETDATE())PRINT @ElapsedDateDELETE FROM WebClientPageState
    WHERE DateSaved < @ElapsedDateGOIF EXISTS (SELECT * FROM dbo.sysobjects WHERE ID = OBJECT_ID(N'GetWebClientPageState') AND XType = 'P')
    BEGIN
    PRINT 'Dropping Procedure GetWebClientPageState' DROP PROCEDURE GetWebClientPageState
    END
    GOPRINT 'Creating Procedure GetWebClientPageState'
    GOCREATE PROCEDURE GetWebClientPageState
    @StateKey UNIQUEIDENTIFIER
    ASSELECT State
    FROM WebClientPageState
    WHERE StateKey = @StateKeyGO2.0 ADAPTER方式
    这下没毛病了吧!这不是我写的