為什麼要檢測資料庫連接是否可用,專案經理說如果實現了這個功能,客戶會認可你的軟體很專業,很好用

來源:互聯網
上載者:User

前幾天,有園友針對我的文章《工作多年後積累的設計靈活,穩定,優秀WinForms應用程式的最佳實務》提出一個問題,說資料庫的應用程式,在儲存資料到SQL Server中去的時候,突然探索資料程式庫伺服器不可用,拋出這個異常

如果使用者很辛苦的輸入了很多資料,點擊儲存時,才探索服務器串連不可用。這時使用者肯定會很惱火,如果你是使用者,你也會覺得很冤枉,辛苦輸入的資料又不能儲存,你幹嗎不早說呢,早點告訴我伺服器不可用,我也可以不用白費功夫。

今天的文章就是為解決這個問題,如何檢測SQL Server 服務是否可用,可以串連,以保證任何時候,使用者輸入資料的工作量不白費,節約客戶的時間,如果發現SQL Server伺服器不可用,要馬上通知使用者,阻止使用者繼續輸入資料。做到軟體是為解決問題,而不是增加麻煩。

我想到的第一個辦法,是在儲存資料的時候,檢測伺服器可否串連,這是必須的,代碼如下

public static bool CheckConnectionAvailableBySql() {         SqlConnection conn = new SqlConnection(ConnectionString);          try          {               conn.Open();               return true;          }          catch (Exception ex) { return false; }}
 

但是,我們要達到的目標不是在儲存資料時檢測,而是使用者開啟程式後,隨時要檢測,於是我想到這樣,再加一個Timer控制項,在它的Tick事件中輪循檢測資料庫服務是否可用

private void timer_Tick(object sender, EventArgs e){        bool available = Program.CheckConnectionAvailableBySql();        if (available)        {                           Console.WriteLine("server is available");        }          }

再把這個封裝成BaseForm表單基類,各種的業務單據輸入表單都繼承於這個表單,這樣就實現了在使用者開啟表單,輸入資料時,隨時可以檢測資料庫連接是否可用。

如果你覺得用SqlConnection會造成對SQL Server服務的效能有影響,可以考慮用網路Ping命令,再配合ServiceProcess物件模型,以提高效能。請看下面的實現代碼

private static bool CheckConnectionAvailableByNetwork(){     bool available = false;     SqlConnectionStringBuilder conection = new SqlConnectionStringBuilder(ConnectionString);     string machineName = conection.DataSource;     Ping ping = new Ping();     PingReply reply = ping.Send(machineName, 4000);     if (reply.Status == IPStatus.Success)     {         ServiceController[] AvailableServices = ServiceController.GetServices(machineName);         foreach (ServiceController AvailableService in AvailableServices)         {            if (AvailableService.ServiceName.Equals("MSSQLSERVER", StringComparison.InvariantCultureIgnoreCase))              {                  if (AvailableService.Status == ServiceControllerStatus.Running)                  {                       available = true;                       break;                  }               }          }     }     return available;}

這個方法是檢測指定的機器的SQL Server服務是否可用,那一句foeach迴圈遍曆改成Linq效率會更好一些。

 

留言的園友提供了另一個實現思路,用網路連接方式,判斷SQL Server是否可用,再把它發送到應用程式中。這個思路在我的ERP Solution已經實現了,現在把它分享出來,供大家參考。

為實現這個功能,分兩個模組,Check SQL Server Available是伺服器檢測程式,檢測SQL Servver是否可用。把它單獨放到一個進程中,Main Form是應用程式,把它理解為用戶端程式,用於輸入資料,儲存到SQL Server中。把檢測SQL Server伺服器是否可用放到一個單獨的進程中,是為了節省Main Form程式的資源,我認為用Timer來輪循SQL Server是否可用,會消耗一些記憶體和CPU,獨立出來,Main Form的效能會好一些。

上面給出的代碼,CheckConnectionAvailableBySql/CheckConnectionAvailableByNetwork和timer_Tick,就是Check SQL Server Available的代碼,下面來分析它如何把SQL Server伺服器是否可用的資訊發送到Main Form應用程式。

這裡使用的是Socket通訊,Check SQL Server Available檢測SQL Servver是否可用,如果可用,發送S字母到Main Form中,不可用則發送F字母到Main Form中,Main Form根據收到的訊息做出處理。如果收到F訊息,表示SQL Server已經不可用,馬上停止當前的工作,讓介面hang-on,效果是這樣的

我在命令列視窗中敲入net stop mssqlserver以停止當前的SQL Server服務。Check SQL Serve Available的timer_Tick事件檢測到SQL Server伺服器已經被停掉,於是發送F到Main Form應用程式,Main Form收到這個字母訊號,知道SQL Server服務不可用,於是掛起當前的表單,顯示Trying to conncet to the server。

再次,我在命令列中輸入net start mssqlserver以啟動SQL Serve。當Check SQL Server Available檢測到之後,會發送S到Main Form中,Main Form知道SQL Server可用,於是恢複當前的介面,允許使用者操作。

為節省網路頻寬,Main Form只接受了Check SQL Server Available發送的一個字母,S表示成功串連到SQL Serve伺服器,successfully,F表示串連失敗,failed。

來分析一下原始碼的實現,檢測SQL Server是否可用的代碼,現在加多了一行發送狀態的語句

private void timer_Tick(object sender, EventArgs e) {      bool available = Program.CheckConnectionAvailableBySql();      if (available)      {                              Program.OnSendData("S"); //succesfully               Console.WriteLine("server is available");       }       else             Program.OnSendData("F"); //failed }

進入到OnSendData方法中,這是標準的Socket 發送字串的代碼,參考如下

 public static void OnSendData(string message) {        try         {                Object objData = message;                byte[] byData = System.Text.Encoding.ASCII.GetBytes(objData.ToString());                m_socClient.Send(byData);          }          catch (SocketException e)          {                //Console.WriteLine(e.ToString());          } }

在表單載入的Load方法中,啟動Socket串連程式,以串連到Main Form的socket介面。

public static void EstablishSocketServer(){     OnConnect("127.0.0.1", 8221);}

在Main Form表單這邊,根據接收到的字元的不同,表現不同的狀態。代碼參考如下

 if (!command.StartsWith("S")) {       TryToConnection dlg = Application.OpenForms["TryToConnection"] as TryToConnection;       if (dlg == null || dlg.IsDisposed)           dlg = new TryToConnection();       dlg.Visible = false;                     dlg.Show(this);       this.Enabled = false;}else{       TryToConnection dlg = Application.OpenForms["TryToConnection"] as TryToConnection;       if (dlg != null)       {           dlg.Visible = false;           dlg.Dispose();           dlg = null;       }       this.Enabled = true;}

關於Socket的介紹,請參考MSDN,在這篇文章中,它的目的是用來傳送SQL Server的可用狀態。如果你熟悉TCP或是UDP的介面,這一部分也可以替換成你熟悉的網路方式。

 

請到epn.codeplex.com下載這篇文章的完整代碼,代碼名稱是SQL Server Available Check。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.