ConnectionTimeout一定要30秒這么久嗎?使用多線程連結數據庫並顯示連接動畫


最近一直在忙於EasyCode.Net代碼生成器2.20的升級版的開發工作,前兩天又有朋友問我EasyCode連結數據庫服務器時,為什么可以5秒內就返回該數據庫是否可以連結的信息,而不是像自己寫的程序會“假死”一樣等待30秒,其實原理很簡單:

1.SqlConnection在用戶名或密碼錯時,返回錯誤信息會很快,但如果主機名或IP地址錯誤,因為網絡訪問的原因,所以即使設置了ConnectionTimeout也沒有效果。

2.如果Connection在訪問一個不存在的服務器,進度將一直等待Connection.Open()方法的結果,對於WinForm將會產生界面假死。

 

所以解決方法也非常簡單:

1.添加一個動畫窗口,顯示連結數據庫動畫,並加上FormClosing事件處理方法,使其不能夠用ALT+F4關閉。

2.另外開起一個線程連結數據庫,並判斷該線程執行時間,如果超過我們指定的時間(比如5秒),就認為無法連結數據庫。

3.通常正常連結數據庫會非常快,為了避免動畫窗口一閃而過,可以設定個動畫窗口顯示的最短時間(比如0.5秒)。

 

我用EasyCode做了一個示例,相關界面、代碼、及程序如下:

 

下面這個是Connection窗口,其中左側的圖標是個GIF動畫圖片:

 

其中多線程連結數據庫代碼,如下:

        private string ConnnectionString;
        private bool ConnSuccess;

        private void BtnTestConn_Click(object sender, EventArgs e)
        {
            ConnnectionString = TxtConnStr.Text;
            ConnSuccess = false;
            TestConnection(500, 3000); //多線程連結數據庫,最少顯示動畫窗口500毫秒,超時時間3000毫秒
        }

        public void TestConnection(int minTimes, int maxTimes)
        {
            FormConnServer formConnServer = new FormConnServer();
            formConnServer.Show();
            formConnServer.CanClose = false;

            Thread makeConnectionThread = new Thread(TestSqlServerConn);
            makeConnectionThread.IsBackground = true;
            makeConnectionThread.Priority = ThreadPriority.Highest;

            makeConnectionThread.Start();

            int sleepTimes = 0;
            while (!ConnSuccess || sleepTimes < minTimes)
            {
                Application.DoEvents();
                Thread.Sleep(50);
                sleepTimes += 50;
                if (sleepTimes > maxTimes)
                {
                    makeConnectionThread.Abort();
                    if (!ConnSuccess)
                        MessageBox.Show("無法與數據庫服務器建立連結,請確認配置信息是否正確。", "系統提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    formConnServer.CanClose = true;
                    formConnServer.Close();
                    return;
                }
            }

            formConnServer.CanClose = true;
            formConnServer.Close();
            MessageBox.Show("與數據庫服務器建立連結成功。".PadRight(50, ' '), "系統提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            return;
        }

        private void TestSqlServerConn()
        {
            SqlConnection sqlConnection = new SqlConnection();
            try
            {
                sqlConnection.ConnectionString = ConnnectionString;
                sqlConnection.Open();
                sqlConnection.Close();
                ConnSuccess = true;
            }
            catch
            {
                sqlConnection.Close();
                ConnSuccess = false;
            }
        }

 

防止動畫窗口被ALT+F4關閉代碼如下:

    public partial class FormConnServer : Form
    {
        public bool CanClose = true;

        public FormConnServer()
        {
            InitializeComponent();
            FormClosing +=new FormClosingEventHandler(FormConnServer_FormClosing);
        }

        private void FormConnServer_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!CanClose)
                e.Cancel = true;
        }
    }

 所有源代碼打包下載:http://files.cnblogs.com/BudEasyCode/ConnDB.rar

代碼很簡單,大家看一下應該都會明白,其實也可以用於連結網絡,復雜耗時計算等應用場景。關於我所設計的EasyCode.Net代碼生成器的2.20升級版本,我們也正在努力的開發和測試過程中,您可以通過我的博客查看該代碼生成器詳細信息,或從我們的官方網站:http://www.budeasycode.com來查看。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM