在我的Windows窗体中,我有这个查询,大约有2,000,000行。 执行查询会冻结界面,大约需要60秒才能完成。
有没有办法可以设置一个进度条,通知用户任务正在进行中?
我是多线程的新手,所以任何帮助都会受到赞赏。
这是花时间的代码:
断点冻结在cmd.executenonquery()
Public Sub InsertNumberswithMsgID(ByVal messageID As Integer, ByVal tableName As String)
Dim cmd As SqlCommand = Nothing
Try
cmd = New SqlCommand(("dbo.[InsertNumbers_withMsgID]"), cn)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("@tablename", tableName)
cmd.Parameters.AddWithValue("@msgid", messageID)
cmd.CommandTimeout = 6000
If Not cn Is Nothing And cn.State = ConnectionState.Closed Then cn.Open()
cmd.ExecuteNonQuery()
Catch ex As SqlException
Catch ex As Exception
Finally
If Not cn Is Nothing And cn.State = ConnectionState.Open Then cn.Close()
If Not cmd Is Nothing Then cmd.Dispose()
End Try
End Function
答案 0 :(得分:1)
Arman提到的article确实是一个很好的起点 - 将它用作代码的骨架,并将函数调用放在sleep命令所在的位置。
但是在您提供的示例中,由于存储过程在一个步骤中执行所有操作并在完成后返回,因此实际上没有办法更新进度栏中的进度。
因此,通过这种方式,您可以在执行前显示0%,然后在完成后显示100%。
或者您必须更改存储过程,以便可以更精细地调用它,即每次处理10%的行,然后返回 - 这将允许您更新进度条(仅在您被允许时才有效)将它分成多个要插入的行块 - 如果你需要在一个事务中将它们保存在一起,那么你当然不能这样做。)
或者,您可以考虑使用进度条的Marquee样式,如here所述。在这种情况下,您根本不需要更新百分比值。
答案 1 :(得分:0)
无论您如何生成工作线程,您需要做的第一件事是禁用UI的部分,这些部分将允许用户再次发出相同的请求,否则用户可能会多次单击按钮,因为所有用户都不耐烦。
要生成您的其他线程以在后台执行SQL工作,请使用BeginExecuteNonQuery函数并将命令对象作为状态变量传递,如果您关心返回受影响的行数。 在通话结束后立即显示进度动画或消息。
然后,在BeginExecuteNonQuery的回调方法中,停止/隐藏进度动画/文本。
以下是一个例子:
Public Sub InsertNumberswithMsgID(ByVal messageID As Integer, ByVal tableName As String)
Dim cmd As SqlCommand = Nothing
Try
cmd = New SqlCommand(("dbo.[InsertNumbers_withMsgID]"), cn)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("@tablename", tableName)
cmd.Parameters.AddWithValue("@msgid", messageID)
cmd.CommandTimeout = 6000
If Not cn Is Nothing And cn.State = ConnectionState.Closed Then cn.Open()
cmd.BeginExecuteNonQuery(FinishInsertingNumbersWithMsgId, cmd)
ShowYourProgressAnimation()
Catch ex As SqlException
Catch ex As Exception
Finally
If Not cn Is Nothing And cn.State = ConnectionState.Open Then cn.Close()
If Not cmd Is Nothing Then cmd.Dispose()
End Try
End Sub
Private Sub FinishInsertingNumbersWithMsgId(ByVal ar As IAsyncResult)
Dim cmd As SqlCommand = ar.AsyncState
cmd.EndExecuteNonEquery(ar)
HideYourProgressAnimation()
End Sub