Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net SqlCommand.BeginExecutenQuery在实际命令结束之前触发回调_Vb.net_Asynchronous_Callback_Ado.net - Fatal编程技术网

Vb.net SqlCommand.BeginExecutenQuery在实际命令结束之前触发回调

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

我有一个长期运行的存储过程,它执行大量计算并更新数千条记录,在内部处理事务以保持每条记录的一致性,同时最大限度地减少阻塞并允许查询流程进度

我正在使用SQLServer2008、.NETFramework4和VB2010

我尝试通过SqlCommand.beginexecutenquery从逻辑层异步调用此SP,并向此方法传递回调以执行某些清理和日志记录,无论命令成功完成还是失败。然而,在SP真正结束之前调用回调函数,AsyncResult.IsCompleted=true,因此,当此回调执行SqlCommand.EndExecuteNonQuery时,它将挂起,等待命令完成或超时过期

我读过很多文章,但到目前为止,这种模式似乎非常简单,而且在任何地方都声明回调只在命令完成后才会触发

简而言之,我的代码基本上是这样的:

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,行为也一样。我看到你在问题中提到了“交易”。剧本有多少个?您是否已确定回调是否在第一个事务结束后启动?如果你只有一个呢?