简体   繁体   中英

DBConnection Time Out Using SQL

I'm using C# to create simple application that will check the database repeatedly after 1 minutes. I'm using thread to make it more manner and reduce resources. These thread will executes one function only at one time in sync.

My problem is

Exception was unhandled : DBConnection
Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.

I understand that my connection with database exceed the time limit. So, how to solve this?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using GDEX.Master;
using GDEX.DataAccess;
using System.Globalization;
using System.IO;
using System.Threading;

namespace SMPPTransfer
{
    public partial class frmDBTS : Form
    {
        string updateProbRecord = string.Empty;
        string selectProbRecord = string.Empty;
        string selectProbStat = string.Empty;
        string updateStat = string.Empty;
        string selectAssignTo = string.Empty;
        string CheckPODStatus = string.Empty;

        DataTable dtStat = null;
        DataTable dtPOD = null;
        DataTable dtAssignNo = null;

        bool stopThreads = false;
        AutoResetEvent blockThread1 = new AutoResetEvent(true);
        AutoResetEvent blockThread2 = new AutoResetEvent(false);

        delegate void SetTextCallback(string text);
        GDexSqlSvConnection dbCon;

        public frmDBTS()
        {
            InitializeComponent();
            String connSQLSvr = "Data Source=<my IP>;Initial Catalog=<database>;User ID=<username>;Password=<pwd>;";
            dbCon = new GDexSqlSvConnection(connSQLSvr);

            Thread thread1 = new Thread(new ThreadStart(UpdateProbRec));
            Thread thread2 = new Thread(new ThreadStart(UpdateProbStat));

            thread1.Start();
            thread2.Start();
        }

        private void UpdateProbRec()
        {
            while (stopThreads == false)
            {
                blockThread1.WaitOne();

                SetText1("Entered Thread 1");
                SetText2("Out Thread 2");                

                //Get POD status
                CheckPODStatus = "select top 100 * from (select cn"
                                 + " FROM gdexpdb.dbo.prob_record where solve = 'N' and status!='S') A "
                                 + " join (select cn, cn_date"
                                 + " from gdexpdb.dbo.pod_data where type='rts' or type = 'pod' or type = 'm_pod' or type = 'm_rts') B "
                                 + "on A.CN=B.cn";

                dtPOD = dbCon.ExecuteQueryAndGetDataTable(CheckPODStatus); //Problem occur from here and only for this function only

                DateTime cnDate;
                string cnDateCon;
                for (int iii = 0; iii < dtPOD.Rows.Count; iii++)
                {
                    cnDate = (DateTime)dtPOD.Rows[iii][2];

                    cnDateCon = cnDate.ToString("yyyy-MM-dd");

                    updateProbRecord = "update gdexpdb.dbo.prob_record set solve='Y', solve_date='" + cnDateCon + "', status='S' "
                                        + "where cn='" + dtPOD.Rows[iii][0] + "'";
                    dbCon.ExecuteNonQuery(updateProbRecord);
                }

                dtPOD.Clear();
                Thread.Sleep(30000);
                blockThread2.Set();
            }
        }

        private void UpdateProbStat()
        {
            while (stopThreads == false)
            {
                blockThread1.WaitOne();

                SetText2("Entered Thread 2");
                SetText1("Out Thread 1");

                selectProbStat = "select username from gdexpdb.dbo.prob_stat";

                dtStat = dbCon.ExecuteQueryAndGetDataTable(selectProbStat);
                int[] userNo = new int[dtStat.Rows.Count];

                for (int x = 0; x < dtStat.Rows.Count; x++)
                {
                    selectAssignTo = "select count(*) as assignNo from gdexpdb.dbo.prob_record where assign_to='" + dtStat.Rows[x][0]+ "'";
                    dtAssignNo = dbCon.ExecuteQueryAndGetDataTable(selectAssignTo);

                    updateStat = "update gdexpdb.dbo.prob_stat set stat=" + dtAssignNo.Rows[0][0] + "where username='" + dtStat.Rows[x][0] + "'";
                    dbCon.ExecuteNonQuery(updateStat);
                }

                dtStat.Clear();
                dtAssignNo.Clear();
                Thread.Sleep(100000);
                blockThread1.Set();
            }
        }

        private void SetText1(string text)
        {
            // InvokeRequired required compares the thread ID of the
            // calling thread to the thread ID of the creating thread.
            // If these threads are different, it returns true.
            if (this.TextThread1.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(SetText1);
                this.Invoke(d, new object[] { text });
            }
            else
            {
                this.TextThread1.Text = text;
            }
        }

        private void SetText2(string text)
        {
            // InvokeRequired required compares the thread ID of the
            // calling thread to the thread ID of the creating thread.
            // If these threads are different, it returns true.
            if (this.TextThread2.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(SetText2);
                this.Invoke(d, new object[] { text });
            }
            else
            {
                this.TextThread2.Text = text;
            }
        }
    }
}

Inside GDexSqlSvConnection class - Functions ExecuteQueryAndGetDataTable , ExecuteNonQuery and others... Set CommandTimeout property to database command instances you are using to query database.

For Example:

MyCommand.CommandTimeout = 120; // 2 Minutes Timeout

You can specify a longer connection timeout in your connection string using the Connect Timeout property. Setting it to 0 means it will not timeout.

Connect Timeout=0

Refer: Connection string options

Although, this will get you past your current problem, what you really need to do is fix your query.

Simple selects and updates should not cause the database to timeout.

To speed up those queries:

  1. Create proper indexes on your tables
  2. Partition your tables, use different file groups if they are very large.
  3. Check the resource allocated to your database server.

超时可以是DbConnection上的ConnectionTimeout或DbCommand上的CommandTimeout-通常是最后一个。

I think this post can help you

SQL Server Connection Timeout Expired

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM