posts - 241,  comments - 116,  trackbacks - 0
          今天在做程序測試的過程中,發(fā)現(xiàn)程序出現(xiàn)只要一個客戶端訪問程序,其他客戶端訪問都受到影響。
          后來一查是在程序中設(shè)了靜態(tài)變量的關(guān)系,由于靜態(tài)變量是全局的所以會出錯。
          對此問題進(jìn)行學(xué)習(xí)一下(下列內(nèi)容來自各個網(wǎng)頁精華,由于截取不同網(wǎng)頁,如有侵權(quán),請和我聯(lián)系):

          利用asp.net 開發(fā)基于B/S模式的應(yīng)用系統(tǒng),經(jīng)常會遇到同一頁面類的各函數(shù)成員之間、 同一會話各頁面之間、不同機器各用戶頁面之間的傳值問題,即要解決數(shù)據(jù)共享的問題。這可以選擇使用Application、Session、cookie、Static、ViewState 等方法實現(xiàn)。
          其中Static變量的使用容易出現(xiàn)問題,使用不好會導(dǎo)致數(shù)據(jù)紊亂,給系統(tǒng)造成故障隱患。
          用ViewState 作為頁內(nèi)數(shù)據(jù)傳值也是一種較好的選擇 。
          2011年06月
          在C#中,static變量表示該變量屬于類,而不是類的實例。可以說是該類的所有實例共享一個static變量。
          asp.net的頁面就是一個類,我們訪問一個頁面。就會在服務(wù)器上實例化一個該類的實例,來響應(yīng)我們的請求。
          “所有實例共享一個static變量” 這就意味著,所有的客戶端訪問到的asp.net頁面中static變量都是同一個變量。
          由于我們每次訪問asp.net頁面都是一個全新的對象,而不是我們上一次訪問的對象。所以上次頁面訪問時我們對頁面中變量的改動都沒有保留。
          遇到這個問題的時候,很多初學(xué)者的直覺就是將這個變量申明為static,自己在測試的時候發(fā)現(xiàn)還真的保留住了頁面的狀態(tài)。竊喜之余沒有發(fā)現(xiàn)這又有引入了另外一個錯誤。因為你要的只是頁面能保留住狀態(tài),而這個狀態(tài)是針對一個客戶端的(session的效果)。而得到的結(jié)果是只要一個客戶端改變了該值所有的其他客戶端都受到了影響(如同Applicatin的效果)。
          究其原因這還要從Asp.net的運行機制談起。在C/S模式軟件開發(fā)過程中,我們通常不會關(guān)心應(yīng)用程序是在哪里運行的,變量存放在哪里,客戶端程序就運行在客戶端,服務(wù)器端程序就運行在服務(wù)器端,一般情況下,二者除了數(shù)據(jù)庫中的數(shù)據(jù)外基本沒有其他共享的問題。 所以這時客戶端的用戶大可放心的使用static變量,因為它們就存放在客戶端程序中。
          于是我們就習(xí)慣的在做B/S模式的頁面時也用static變量,殊不知Asp.net中的static已 不同于C/S中的static。是因為在Asp.net中所有的用戶將使用同一個static變量。這就意味 著每一個使用該頁面的用戶對該變量的操作將會影響到其他用戶。
          解決的辦法之一是可以選擇Asp.net提供的ViewState對象。ViewState對象可以用來保存頁面中的各種變量,甚至是對象。“有些數(shù)據(jù)可以直接保存到ViewState中,諸如字符串 、整數(shù)、布爾、數(shù)組里表、哈希表等。”
          “所謂ViewState,實際上是一些鍵值對,ASP.NET通過它維護網(wǎng)頁和服務(wù)器的狀態(tài),并將ViewState封裝成一個或幾個隱藏的表單域傳遞到客戶端。而客戶端提交時,ViewState也 將被提交到服務(wù)器端。這樣后續(xù)的請求可以獲得上一次請求的狀態(tài)。”
          只要用變量名稱做索引,如ViewState[“Var ”], 就可以存取變量Var的值,而不管Var是普通變量,還是對象,甚至是內(nèi)存中的一張DataTabl e。服務(wù)器端會為每個連接到該頁面的用戶分別建立一個ViewState,所以ViewState相當(dāng)于 頁面級的Session。相當(dāng)于頁面全局變量,但是一旦退出當(dāng)前頁面,它就會丟失。
          ViewState的用法很簡單,如下所示:
          1、保存變量到ViewState中(賦值):
           ViewState[“times”]=times;     //存放普通變量times
           ViewState[“Orders”]=dtOrders;  //存放DataTable型對象dtOrders
             ViewState  ["aa"] ="123";
          2、讀出ViewState中的值(取值):
                times =  (int)ViewState[“times”];
            dtOrders =  (DataTable)ViewState[“Orders”];
          Java
             string bb =  ViewState["aa"].ToString();
          讀出變量的值時要進(jìn)行強制類型轉(zhuǎn)換,這是因為當(dāng)變量(不管是int型的普通變量times ,還是DataTable型的對象dtOrders)被存放到ViewState中后統(tǒng)統(tǒng)按Object類型存放。所以 當(dāng)我們從ViewState取出時,一定要轉(zhuǎn)換成相應(yīng)的類型,否則就會報錯。在變量保存到ViewS tate中時,系統(tǒng)會自動轉(zhuǎn)換。
          這不是說static型變量就沒用了,在C#中用static聲明的類不用實例化直接使用。正是由于所有用戶共享服務(wù)器端的同一個static變量,所以可以用static型對象來存取一些公用的處理模塊,比如類型轉(zhuǎn)換、變量驗證等工作。所以要根據(jù)具體情況而定。
          還有一點需要注意:如果在頁面中多個過程要共享一個對象或變量,我們在頁面類的開始部分定義一個頁面級的全局變量是不行的,static本來可以,但上面說了這種類型的變量不安全,所以這時就可以用ViewState。
          ViewState是將數(shù)據(jù)存入到頁面隱藏控件里,不再占用服務(wù)器資源,因此, 我們可以將一 些需要服務(wù)器"記住"的變量和對象保存到viewstate里面。viewstate并不能存儲所有的.net 類型數(shù)據(jù),它僅僅支持String、Integer、Boolean、Array、ArrayList、Hashtable 以及自定義的一些類型。
          ViewState 常用于保存單個用戶的狀態(tài)信息,生存期等于頁面的生存期。viewstate是 在本頁面之內(nèi)各函數(shù)間進(jìn)行傳值的 , 至于為什么要使用這種方法是因為在一個事件發(fā)生之后 , 頁面可能會刷新 , 如果定義全局變量會被清零 , 所以要使用 viewstate保持?jǐn)?shù)據(jù),任何事物都有兩面性, 因為ViewState變量在客戶端實際上是用<input type=“hidden ”  value=“ADFAIB3P234P-AFAFAF……”/>保存的一個對象,這樣如果要保存的是個對象, 甚 至是個很復(fù)雜的對象(如DataTable),這樣以來就會增加網(wǎng)絡(luò)傳輸?shù)呢?fù)擔(dān)。 使用viewstat e會增加頁面html的輸出量,占用更多的帶寬,這一點是需要慎重考慮的。另外, 由于所有的v iewstate都是存儲在一個隱藏域里面,用戶可以很容易的通過查看源碼來看到這個經(jīng)過base6 4編碼的值,然后再經(jīng)過轉(zhuǎn)換就可以獲取你存儲其中的對象和變量值。
          ViewState只能在一個頁面上傳值(session可跨多個頁面?zhèn)髦担琕iewState只是在當(dāng)前page內(nèi)有效,關(guān)了當(dāng)前頁,再重新打開,ViewState所保存的值也就消失了。需要在用戶訪問一個頁面時保持一個變量的值,并隨時改變它的值,用ViewState好些。ViewState是用來同步客戶端與服務(wù)端的變量狀態(tài)的!當(dāng)有兩個用戶對同一頁面進(jìn)行操作時,若使用Static出現(xiàn)了數(shù)據(jù)張冠李戴的嚴(yán)重錯誤時,改為ViewState后就會一切正常了。
          開發(fā)C/S模式的系統(tǒng)和開發(fā)B/S模式的系統(tǒng)有很大的不同。因此我們一定要根據(jù)不同情況正確理解各種變量的作用域和生存期,以便能夠正確使用各種保存數(shù)據(jù)的方法而不至于出現(xiàn) 錯誤。
          posted on 2011-09-06 10:07 墻頭草 閱讀(273) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          人人游戲網(wǎng) 軟件開發(fā)網(wǎng) 貨運專家
          主站蜘蛛池模板: 永嘉县| 崇文区| 青海省| 中阳县| 元氏县| 梁山县| 内乡县| 惠水县| 临泽县| 家居| 兰坪| 视频| 永登县| 金塔县| 宁蒗| 盐边县| 怀化市| 仙游县| 定远县| 那曲县| 永川市| 石屏县| 和龙市| 隆尧县| 富源县| 鄂伦春自治旗| 崇仁县| 二手房| 靖江市| 望江县| 即墨市| 金堂县| 六盘水市| 高雄县| 广宗县| 东丰县| 图们市| 集贤县| 凉山| 景洪市| 东源县|