Vb.net SqlCommand.BeginExecutenQuery在实际命令结束之前触发回调
我有一个长期运行的存储过程,它执行大量计算并更新数千条记录,在内部处理事务以保持每条记录的一致性,同时最大限度地减少阻塞并允许查询流程进度 我正在使用SQLServer2008、.NETFramework4和VB2010 我尝试通过SqlCommand.beginexecutenquery从逻辑层异步调用此SP,并向此方法传递回调以执行某些清理和日志记录,无论命令成功完成还是失败。然而,在SP真正结束之前调用回调函数,AsyncResult.IsCompleted=true,因此,当此回调执行SqlCommand.EndExecuteNonQuery时,它将挂起,等待命令完成或超时过期 我读过很多文章,但到目前为止,这种模式似乎非常简单,而且在任何地方都声明回调只在命令完成后才会触发 简而言之,我的代码基本上是这样的:Vb.net SqlCommand.BeginExecutenQuery在实际命令结束之前触发回调,vb.net,asynchronous,callback,ado.net,Vb.net,Asynchronous,Callback,Ado.net,我有一个长期运行的存储过程,它执行大量计算并更新数千条记录,在内部处理事务以保持每条记录的一致性,同时最大限度地减少阻塞并允许查询流程进度 我正在使用SQLServer2008、.NETFramework4和VB2010 我尝试通过SqlCommand.beginexecutenquery从逻辑层异步调用此SP,并向此方法传递回调以执行某些清理和日志记录,无论命令成功完成还是失败。然而,在SP真正结束之前调用回调函数,AsyncResult.IsCompleted=true,因此,当此回调执行S
Public Shared Sub ExecAsync(sp_call As String, async_connection As String)
'...
Dim cmd As SqlClient.SqlCommand = New SqlClient.SqlCommand(sp_call, New SqlClient.SqlConnection(async_connection))
Dim callback As New AsyncCallback(AddressOf CallbackAsync)
cmd.BeginExecuteNonQuery(callback, cmd)
'...
'try catch ommited
End Sub
Public Shared Sub CallbackAsync(ByVal result As IAsyncResult)
Dim cmd As SqlClient.SqlCommand = TryCast(result.AsyncState, SqlClient.SqlCommand)
cmd.EndExecuteNonQuery(result)
If cmd.Connection IsNotNothing Then
cmd.Connection.Close()
End If
'...
'try catch and logging ommited
End Sub
我可以用这个简单的脚本模拟真实SP的行为:
declare @i int
declare @iId int
select @iId = 1
select @i = 0
delete xxx_xxx --trivial test table
where id = @iId
while @i < 100
begin
begin transaction
insert into xxx_xxx (id, hora, iNum) values (@iId, getdate(), @i)
commit transaction
select @i += 1
WAITFOR DELAY '00:00:01'
end
declare@i int
声明@iId int
选择@iId=1
选择@i=0
删除xxx_xxx——普通测试表
其中id=@iId
而@i<100
开始
开始交易
在xxx_xxx(id,hora,iNum)中插入值(@iId,getdate(),@i)
提交事务
选择@i+=1
等待延迟“00:00:01”
终止
在我所做的许多尝试中,我发现如果我删除SQL脚本中的事务,那么行为就是预期的,回调将在执行的最后触发。
执行回调在执行结束前激发的事务,注释掉它们,它在执行结束时激发
不幸的是,在真实场景中,避免交易不是一种选择
这有什么原因吗?或者更准确地说,有什么方法可以避免它,并在SP结束后实际调用回调函数
任何帮助都将不胜感激。
先谢谢你
古斯塔沃·索萨(Gustavo Sosa)你能在这一行之后发布你的代码吗:
cmd.beginecutenquery(callback,cmd)
你有没有试过用ExecuteReader
而不是ExecuteNonQuery
,只是为了查看行为?@BateTech,在cmd.beginecutenquery之后,我只捕获任何异常和子端。@Josh Part,是的,我也试过BeginExecuteReader,行为也一样。我看到你在问题中提到了“交易”。剧本有多少个?您是否已确定回调是否在第一个事务结束后启动?如果你只有一个呢?