ADONET 异步执行 - 连接中断错误
ADONET async execution - connection broken error
我正在尝试执行一些 time.My 的异步查询,目标是执行简单的 SQL 语句,不要等待它们完成。下面的代码适用于 10、500 或 1000 甚至 5000 个查询。但是对于 50000 个查询突然出现错误并说
"BeginExecuteReader requires an open and available Connection. The connection's current state is open."
有时它说“......状态是:坏了”
这是 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 class, 连接池和重新连接逻辑"一文不是答案。我的问题是异步执行。
我尝试使用该代码。我试过不使用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 个命令。我应该怎么做才能避免内存问题或池限制?
经过多次尝试,我发现了这些:(可能是我知识不够)
async SQL 查询执行困难。你不能轻易捕捉到错误,如果你破坏了连接对象,你就不能触发异步回调函数。
显然它的设计目的不是一次执行 50.000 个查询。如果你认为这不会发生在现实生活中,我不反对。
相反,我使用了简单的解决方案:
HostingEnvironment.QueueBackgroundWorkItem(Function(token) myTestClass.myExecute_Async(sqlstr, token))
for...下一条语句中有 50.000 个查询,执行时间为零秒。当然他们在排队,我查看了 sql table 并且每次我 运行 SELECT COUNT(1) FROM test1 我都增加了将近 1 分钟的记录数。它插入的记录数是 exactlu 50.001(我从零开始寻找下一个),我觉得它更可靠。至少我明白幕后发生了什么。
IIS 内存使用率超过 114.000k,return 正常回到 19.000k。
我希望这在某些时候对其他人有所帮助。
谢谢我的朋友们。
对于那些试图处理繁重事务负载或对主题感兴趣的人:
最好的选择是hangfire。我也试验了线程,它有效,但我认为我们的 hangfire 更简单,你不需要担心 web 池重新启动,任何事情都可能像错误一样停止 IIS 服务......
我调用了一个 class 将 10.000 条记录插入到 sql 服务器,我调用了 for..next 100 次。当然需要很长时间,但它就像一个魅力。我还杀死了 IIS 进程,然后一切都停止了。当我再次启动 IIS 时,一切都从它应该的地方继续。
我更喜欢这个解决方案。
谢谢。
我正在尝试执行一些 time.My 的异步查询,目标是执行简单的 SQL 语句,不要等待它们完成。下面的代码适用于 10、500 或 1000 甚至 5000 个查询。但是对于 50000 个查询突然出现错误并说
"BeginExecuteReader requires an open and available Connection. The connection's current state is open." 有时它说“......状态是:坏了”
这是 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 class, 连接池和重新连接逻辑"一文不是答案。我的问题是异步执行。
我尝试使用该代码。我试过不使用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 个命令。我应该怎么做才能避免内存问题或池限制?
经过多次尝试,我发现了这些:(可能是我知识不够)
async SQL 查询执行困难。你不能轻易捕捉到错误,如果你破坏了连接对象,你就不能触发异步回调函数。
显然它的设计目的不是一次执行 50.000 个查询。如果你认为这不会发生在现实生活中,我不反对。
相反,我使用了简单的解决方案:
HostingEnvironment.QueueBackgroundWorkItem(Function(token) myTestClass.myExecute_Async(sqlstr, token))
for...下一条语句中有 50.000 个查询,执行时间为零秒。当然他们在排队,我查看了 sql table 并且每次我 运行 SELECT COUNT(1) FROM test1 我都增加了将近 1 分钟的记录数。它插入的记录数是 exactlu 50.001(我从零开始寻找下一个),我觉得它更可靠。至少我明白幕后发生了什么。 IIS 内存使用率超过 114.000k,return 正常回到 19.000k。
我希望这在某些时候对其他人有所帮助。
谢谢我的朋友们。
对于那些试图处理繁重事务负载或对主题感兴趣的人:
最好的选择是hangfire。我也试验了线程,它有效,但我认为我们的 hangfire 更简单,你不需要担心 web 池重新启动,任何事情都可能像错误一样停止 IIS 服务......
我调用了一个 class 将 10.000 条记录插入到 sql 服务器,我调用了 for..next 100 次。当然需要很长时间,但它就像一个魅力。我还杀死了 IIS 进程,然后一切都停止了。当我再次启动 IIS 时,一切都从它应该的地方继续。
我更喜欢这个解决方案。
谢谢。