2013-08-29 33 views
0

我被要求做一個系統,每秒輪詢一個數據庫中的一個表,並且它是否符合滿足標準啓動操作來處理該行的一行。vb.net polling SQL Server每秒一次造成超時

我已經完成了這項工作,但每隔一段時間我都會遇到超時異常。我有一個WPF應用程序,我有一個線程在後臺運行。這個線程有一個循環,並在循環結束時睡一秒鐘。連接到數據庫在「using」子句中打開。

下面是我的線程子:

Private Sub PollDatabase() 
    While m_StopThread = False 
     Try 
     Dim listOfRows As List(Of DataObject) = db.GetDataObjects() 

     ... Do something with the rows ... 

     Catch ex As Exception 
      m_log.WriteLine(ex.ToString()) 
     End Try 
    Thread.Sleep(1000) 
    End While 
End Sub 

我的SQL函數如下所示:

Public Function GetDataObjects() As List(Of DataObject) 
    Dim result As New List(Of DataObject) 
    Dim sb As New StringBuilder("... the sql query ...") 

    Using cnn = New SqlConnection(_connectionString) 
     cnn.Open() 
     Using cmd = New SqlCommand(sb.ToString(), cnn) 
      cmd.CommandTimeout = 0 
      Using DataReader As SqlDataReader = cmd.ExecuteReader() 
      Do While DataReader.Read() 
       ... read the columns from table 
        to the dataobject ... 
       result.Add(DataObject) 
      Loop 
      End Using 
     End Using 
    End Using 
    Return result 
End Function 

現在似乎什麼隨機我的日誌有一個超時異常:

System.Data.SqlClient.SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. 
... 
at System.Data.SqlClient.SqlConnection.Open() 

我的問題是:這樣做是否存在這樣做的方式?或者我在這裏做了一些根本性的錯誤?當然如果有人有解決這個問題的建議。

編輯:

我試着用SQL函數有點不同的方法。當我的應用程序啓動並拋棄「使用」子句時,我現在打開一個連接。所以我現在的功能看起來像這樣:

Public Function GetDataObjects() As List(Of DataObject) 
    Dim result As New List(Of DataObject) 
    Dim sb As New StringBuilder("... the sql query ...") 
    _sqlCmd.CommandText = sb.ToString() 

    Using DataReader As SqlDataReader = _sqlCmd.ExecuteReader() 
     Do While DataReader.Read() 
     ... fill the list with objects ... 
     Loop 
    End Using 

    Return result 
End Function 

我的日誌是乾淨的表單錯誤。那麼是否有什麼問題在一秒鐘內打開與服務器的連接?

編輯:

我已經做了很多測試,現在找出問題所在。我發現,多次連接到服務器並不會造成任何問題。在連接後添加select語句也沒有。但是當我真正實現一個功能,其中是完整的閱讀器部分,並返回我的結果時,我遇到了超時問題。這裏有兩個例子。

這不是導致問題:

Private Sub Window_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs) 
    Me.DataContext = Me 
    m_Thread = New Thread(AddressOf ConnectionTestFunction) 
    m_Thread.IsBackground = True 
    m_Thread.Start() 
End Sub 

Private Sub ConnectionTestFunction() 
    While m_stopThread = False 
     Try 
      m_log.WriteLine("GetData (" & m_ThreadCounter & ")") 
      Using cnn As SqlConnection = New SqlConnection("Data Source=server;Initial Catalog=db;Integrated Security=True;MultipleActiveResultSets=True") 
       cnn.Open() 
       Using cmd As SqlCommand = New SqlCommand("SELECT * FROM Data", cnn) 
        Using DataReader As SqlDataReader = cmd.ExecuteReader() 
         Do While DataReader.Read() 
         Loop 
        End Using 
       End Using 
      End Using 
     Catch ex As Exception 
      m_log.WriteLine(ex.ToString()) 
     End Try 
     m_ThreadCounter += 1 
     Thread.Sleep(1000) 
    End While 
End Sub 

這導致超時錯誤:

Private Sub Window_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs) 
    Me.DataContext = Me 
    m_Thread = New Thread(AddressOf ConnectionTestFunction) 
    m_Thread.IsBackground = True 
    m_Thread.Start() 
End Sub 

Private Sub ConnectionTestFunction() 
    While m_stopThread = False 
     Try 
      m_log.WriteLine("GetData (" & m_ThreadCounter & ")") 
      Dim datarows As List(Of Data) = Me.GetData() 
     Catch ex As Exception 
      m_log.WriteLine(ex.ToString()) 
     End Try 
     m_ThreadCounter += 1 
     Thread.Sleep(1000) 
    End While 
End Sub 

Private Function GetData() As List(Of Data) 
    Dim result As New List(Of Data) 
    Using cnn As SqlConnection = New SqlConnection("Data Source=server;Initial Catalog=db;Integrated Security=True;MultipleActiveResultSets=True") 
     cnn.Open() 
     Using cmd As SqlCommand = New SqlCommand("SELECT * FROM Data", cnn) 
      Using DataReader As SqlDataReader = cmd.ExecuteReader() 
       Do While DataReader.Read() 
        Dim d As New Data() 
        d.DataId = DataReader("DataId") 
        ... etc fields about 10 of them ... 
        result.Add(d) 
       Loop 
      End Using 
     End Using 
    End Using 
    Return result 
End Function 

我真的很高興,如果有人對此有任何的想法......我不得不承認我現在很困惑。

+0

你看過SQL日誌嗎?你的服務器正忙嗎?你有Exchange安裝在同一個盒子上嗎? – peterG

+0

嘿,彼得,不,我沒有交換。服務器不是非常繁重的使用。它內部使用五個人左右。 – japesu

+0

和SQL日誌? – peterG

回答

0

也許,您的代碼完成所需的時間比連接的默認超時值要長。嘗試在創建Sql連接時指定超時值。確保它比您的代碼需要完成的時間更長。

0

這種方法看起來不太好..而不是彙集,爲什麼不響應新數據時呢?你可以使用觸發器或SqlDependency?

http://dotnet.dzone.com/articles/c-sqldependency-monitoring

+0

Heya,我無法在SQL Server上做任何事情。我無法添加觸發器,程序等。但我可以用我的vb.net代碼做任何事情。我會看看SqlDepency,這對我來說是一個新課題。 – japesu

+0

不幸的是,看起來像SqlDepency也是沒有問題:(這可能是一個非常好的解決方案,看起來像應該使用的東西,但我的老闆說,因爲我們在別處有類似的代碼,我們應該這樣做,並找出爲什麼我在使用「using」子句時出現錯誤,而不是隻打開一個連接而不是嘗試解決問題,所以我的問題仍然是每次需要提交一些sql時打開一個新連接是錯誤的? – japesu