vb.net每秒轮询一次Sql server导致超时

时间:2013-08-29 11:03:50

标签: sql vb.net sql-server-2008 tsql vb.net-2010

我被要求做一个系统,该系统每秒轮询一次数据库中的一个表,如果它反对符合条件的行开始处理该行的动作。

我已经做到了这一点,但我时不时地得到一个例外。我有一个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函数不同的方法。我现在在应用程序启动时打开一个连接并转储“using”子句。所以我的函数现在看起来像这样:

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

如果有人对此有任何想法,我真的很高兴......我不得不承认我现在真的很困惑。

2 个答案:

答案 0 :(得分:0)

您的代码可能需要比连接的默认超时值更长的时间才能完成。尝试在创建Sql连接时指定超时。确保它比代码完成所需的时间更长。

答案 1 :(得分:0)

这种方法看起来不是很好..为什么不在新数据到来时做出反应?您可以使用触发器或SqlDependency?

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