2012-06-21 17 views
2

我使用C#創建簡單的應用程序將在1分鐘後反覆檢查數據庫。我正在使用線程使其更加方式並減少資源。這些線程只會同時執行一個函數。DBConnection的超時使用SQL

我的問題是

例外是未處理:DBConnection的
超時過期。之前的操作的完成的超時 時間已過或服務器是 沒有響應。

我明白,我與數據庫的連接超過時間限制。那麼,如何解決這個問題呢?

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; 
      } 
     } 
    } 
} 
+0

你有什麼已經嘗試過呢? – linkerro

+2

哪一行引發異常? –

+0

爲什麼不使用計時器? –

回答

4

GDexSqlSvConnection類 - 功能ExecuteQueryAndGetDataTableExecuteNonQuery等...設置CommandTimeout屬性爲您正在使用查詢數據庫的數據庫命令實例。

例如:

MyCommand.CommandTimeout = 120; // 2 Minutes Timeout 
+0

如果根據代碼..我應該把它放在哪裏? – akuhero

+0

Inside ExecuteQueryAndGetDataTable函數 – Dusan

+0

謝謝你的回覆.. – akuhero

2

您可以使用Connect Timeout屬性來指定您的連接字符串中較長的連接超時。將其設置爲0意味着它不會超時。

Connect Timeout=0 

參見:Connection string options

雖然,這將讓你過去你當前的問題,你真正需要做的是解決您的查詢。

簡單的選擇和更新不應導致數據庫超時。

爲了加快這些查詢:

  1. 上的表格中
  2. 創建適當的索引的分區你的表,使用不同的文件組,如果他們是非常大的。
  3. 檢查分配給數據庫服務器的資源。
+0

他得到的錯誤不是由連接的超時造成的,而是由命令超時造成的(錯誤消息有點錯誤)。在連接字符串中設置連接超時將不起作用。 – Dusan

+0

不過,他的查詢很簡單,不應該超時。索引,分區和資源分配都會比增加CommandTimeout更好。 – nunespascal

+0

我完全同意 – Dusan

1

超時可以是您的DbConnection上的ConnectionTimeout或DbCommand上的CommandTimeout - 通常是最後一次。