程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> 在效率和可靠性之間掙扎

在效率和可靠性之間掙扎

編輯:.NET實例教程
寫程序,完成功能是最基本的要求,但要應對真實世界的各種情況,則會追求多種目標,如性能、穩定性、可擴展性、可維護性等。然而,在某一個歷史階段,有些目標之間是相互沖突的,需要程序設計人員選擇合適的策略,在沖突與矛盾中尋求平衡,以達到最佳的綜合效果。其中,效率和可靠性但是一對矛盾,需要小心面對。

舉個例來說,使用ASP.Net從SQL Server數據庫中讀取數據時,我們一般會使用SqlDataReader。.如: SqlDataReader reader = cmd.ExecuteReader();
獲得reader對象之後,一般采用循環語句逐條讀出記錄,如
while(reader.Read())
{
       reader[“UserName”].value.ToString();
       reader.GetString(1);
}

在上面的循環語句中,我采用了兩種方法來讀取數據。第一個語句讀取記錄的第1個字段:UserName,並將其轉換成字符串,第二條語句直接根據索引號,返回字符串。已經有很多文章說明,用第2條語句的方法比用第1條語句的方法,效率更高(可以去理解和測試一下)。

毫無疑問,我在程序中會追捧第2第語句的方法,即便只會帶來少許的性能提高,在成千上萬次數據讀取中,差別就明顯了。

根據效率優先原則,我選擇了第2條語句所采用的方法來讀取數據。但問題猶如幽靈,總會在你得意時對你當頭一棒!假設字段的內容為空(在這數據庫表中大量存在)時,你將會遭遇一個錯誤:“數據為空。不能對空值調用此方法或屬性。”這個錯誤會讓你手足無措。

但是,你采用第1條語句的方法,在字段值為空時,卻不會有前面的錯誤。由此可推斷,微軟在實現GetString()時,並沒有打算處理數據為空的情況。效率優先原則在這裡遭遇了挫折。系統漏洞百出,再高的效率也沒有多大意義,尤其對於面向公眾的信息網站來講,更是這樣。

是不是就放棄第2條語句的方法,全部采用第1條語句的方法呢?如果能夠盡可能利用兩種方法的優點就更好了。
解決這個問題就要摒棄一刀切,根據具體情況具體分析。如果字段在定義時就不能為空的,就可以不用考慮空值的情況,采用第2條語句的方法,以提高效率。如果字段定義可以為空時,則采用第1條語句的方法,以提高可靠性。

當然,也可以先進行空值判斷,再采用第2條語句的方法,如:
string userName = reader.IsDBNull(1)?null:reader.Getstring(1);

這樣,就可以在保證可靠性和提高效率之間都有所照顧。

類似這樣的效率與可靠性之間的矛盾,在程序中大量存在。有時可能為了應付發生概率很小的意外,卻要寫上大段大段的代碼來進行檢測、分析和處理。

從某處看了一段使用FileUpload控件來上傳圖象的代碼。點擊浏覽按鈕,可以選擇相應圖片文件,並使文件全路徑顯示在控件的文本框中。然後再通過一段代碼來實現上傳:

            imagePath = upImage.PostedFile.FileName;
            //取得圖片類型
            imageType = imagePath.Substring(imagePath.LastIndexOf(".") + 1);
            //取得圖片名稱
        

$False$

   imageName = imagePath.Substring(imagePath.LastIndexOf("\\") + 1);
            string tmp = imageName.Split(''.'')[0];
            string hashImageName =tmp.GetHashCode().ToString() + "." + imageType;
 
            //判斷是否指定圖片格式
            if ("jpg" == imageType || "JPG" == imageType || "gif" == imageType || "GIF" == imageType || "bmp" == imageType || "BMP" == imageType || "Bmp" == imageType)
            {
                imageUrl = "~/Images/" + hashImageName;
                try
                {
                    //建立虛擬路徑>                    mPath = Server.MapPath("~/Images");
                    //保存到虛擬路徑
                    upImage.PostedFile.SaveAs(mPath + "\\" + hashImageName);
                    Response.Write("圖片上傳成功!");
                }
                catch(Exception err)
                {
                    Response.Write(err.Message + ",圖片上傳失敗!");
                }
            }
            else
            {
                Response.Write("<script language=''Javascript''> alert(''對不起!請您選擇jpg/bmp/gif格式的圖片!'');</script>");
                return;
            }      
        }
 
這一段代碼,對文件格式進行了判斷,如果格式是指定的圖片格式之一,則執行上傳。一般情況下,這段程序沒有問題。但是,當我選擇了圖片之後,卻人為修改了控件文本框中的路徑和文件信息,修改後的文件可能並不存在,此時會發生什麼呢?

我曾以為程序不會正常運行,上傳圖片會失敗。然後實驗的結果卻是顯示了“圖片上傳成功!”。查看服務器上圖片文件夾,發現確實有了指定的文件名,但圖像大小為0字節。這說明這個成功的信息是個假象!(看來有必要去理解SaveAs()的真實原理)。

為了防止原文件不存在,卻能上傳成功的假象出現,在進行上傳之前,有必要對原文件是否存在進行驗證。於是我前面的代碼前加了一個判斷語句:

if (File.Exists(upImage.PostedFile.FileName))
{
}

這樣,就可以得到這樣一個邏輯:
邏輯圖


 這一個流程圖,兩次判斷對於大多數操作來講,沒有任何意義,如果不要這兩個判斷,效率會更高。但對於少數不按“規矩”辦事的操作來講,這兩次判斷必不可少,沒有就會出現問題。

總而言之,要做優雅的程序,需要缜密的思考,仔細應對意外情況,同時盡可能保證效率,才能使程序的最大限度地接近期望的目標。 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved