【发布时间】:2015-03-22 07:29:22
【问题描述】:
我正在尝试异步查询执行一段时间。我的目标是执行简单的 SQL 语句,而不是等待它们完成。以下代码适用于 10、500 或 1000 甚至 5000 个查询。但是对于 50000 个查询,突然出现错误并说
“BeginExecuteReader 需要一个打开且可用的连接。连接的当前状态是打开的。” 有时它会说“......状态是:坏了”
这是 aspnet 测试站点,我认为可能会发生 50.000 个查询。是我错过了什么吗?它不应该工作吗?
我使用 windows7 x64,我相信它与 sql 连接轮询限制有关。你可能会说 50.000 太高了,但我需要避免这个错误以信任代码,我不知道如何。
ps:在代码中,我打开了连接,但没有出于测试目的关闭它。如果我关闭连接回调函数永远不会触发。
有什么建议吗?而且google上关于这个错误的信息并不多。
Partial Class test
Inherits System.Web.UI.Page
Dim cnTest As SqlConnection
Protected Sub cmdAsyncTest_Click(sender As Object, e As EventArgs) Handles cmdAsyncTest.Click
Dim s As String = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
Dim sqlstr As String
Dim x1 As Integer, x2 As Integer, i As Integer
sqlstr = "INSERT INTO test1 (name,surname,a2) VALUES ('" & s & "','" & s & "',5)"
Dim cnstr As String = System.Configuration.ConfigurationManager.ConnectionStrings("ConnectionStringLOG").ConnectionString
cnTest = New SqlConnection(cnstr)
cnTest.Open()
watch = Stopwatch.StartNew()
For i = 0 To 50000
myExecute_Async(sqlstr)
Next
End Sub
Function myExecute_Async(ByVal sqlstr As String) As String
Using cmd As New SqlCommand(sqlstr, cnTest)
cmd.CommandType = CommandType.Text
cmd.BeginExecuteReader(New AsyncCallback(AddressOf QueryCallback), cmd)
Return ""
End Using
End Function
Sub QueryCallback(ByVal async As IAsyncResult)
' ToDo: something
End Sub
End Class
CREATE TABLE [dbo].[test1](
[ID] [int] IDENTITY(1,1) NOT NULL,
[name] [varchar](50) NULL,
[surname] [varchar](50) NULL,
[a2] [int] NULL,
CONSTRAINT [PK_test1] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
“.NET SqlConnection 类、连接池和重新连接逻辑”一文不是答案。我的问题是异步执行。
我尝试使用该代码。我尝试不使用 sun 例程:
Dim cnstr As String = System.Configuration.ConfigurationManager.ConnectionStrings("ConnectionStringLOG").ConnectionString
cnTest = New SqlConnection(cnstr)
cnTest.Open()
watch = Stopwatch.StartNew()
For i = 0 To 50000
Using cmd As New SqlCommand(sqlstr, cnTest)
' Return "" & cmd.ExecuteNonQuery()
cmd.CommandType = CommandType.Text
cmd.BeginExecuteReader(New AsyncCallback(AddressOf QueryCallback), cmd)
End Using
Next
这次我抛出了“System.OutOfMemoryException”类型的异常。在 cmd.BeginExecuteReader 行。
假设我有需要运行这 50.000 条命令的逻辑。我应该怎么做才能避免内存问题或池限制?
【问题讨论】:
-
这就是我首先尝试的。但是在 myExecute_Async 结束时,当您关闭连接(或不使用)时,连接将从内存中消失,并且不会调用回调函数。很奇怪,但您也没有收到任何错误消息。回调函数根本没有命中。
-
抱歉,“.NET SqlConnection 类、连接池和重新连接逻辑”一文不是答案。我的问题是异步执行。无论如何,谢谢。
-
你还在使用同一个连接...
-
我尝试通过“使用”命令在子程序中打开连接。在那种情况下,异步执行对我来说失去了所有优势。速度与同步执行相同。甚至更长。 5000 个同步命令需要 26 秒,5000 个异步命令需要 32 秒。
-
是的,不要那样做,我误读了你的问题。我建议你改用TPL。如果您使用 VS >= 12,请使用 Async and Await 关键字。
标签: asp.net sql-server vb.net asynchronous