如何显示进度条在执行大的SqlCommand VB.Net进度条、SqlCommand、Net、VB

2023-09-04 00:04:12 作者:心跳多久伴你多久

我有一个通常返回20 000这个大的SQL命令 - 100 000行数据。 但只要我称之为executeMyQuery功能,该程序挂起几秒钟,这取决于如何大的回报。

我只返回一个列。

如何显示一个进度条,而此命令运行?

也许在一个线程或东西(我有一个线程没有经验)

下面是我的code(该参数从3个不同的combobox.selectedItem发送):

 公共功能executeMyQuery(数据库作为字符串,colname需要作为字符串,tblname作为字符串)
    尝试
        ListBox1.Items.Clear()
        如果不String.IsNullOrWhiteSpace(CONNSTRING)然后
            使用CN作为SqlConnection的=新的SqlConnection(CONNSTRING)
                cn.Open()
                使用CMD作为的SqlCommand =新的SqlCommand()
                    cmd.Connection = CN
                    昏暗QRY作为字符串
                    QRY =的String.Format(选择不同的[{0}]从{1} .dbo。{2}其中[{0}]不为空,colname需要,DBNAME,tblname)
                    cmd.CommandText = QRY
                    cmd.CommandTimeout = 0

                    昏暗的计数为整数
                    使用myReader作为SqlDataReader的= cmd.ExecuteReader()
                        虽然(myReader.Read())
                            数+ = 1
                            ListBox1.Items.Add(count.ToString&安培;&安培。; myReader.GetString(0))
                        结束在
                    结束使用
                结束使用
            结束使用
        结束如果
         cn.Close()
    抓住EX为例外
        MSGBOX(出错:&放大器; ex.Message)
        cn.Close()
    结束
端功能
 

解决方案 vb中进度条的使用

下面是如何做到Asychrounous工作,VB.Net 4.0砍倒的例子。

让想象你有一个具有以下进口形式,

 进口System.Windows.Forms的
进口的System.Threading
进口System.Threading.Tasks
 

这表有两个控件

 私人WithEvents就DoSomthing为按钮
私人WithEvents就进展进度
 

放在你的应用程序,我们有一个功能名为 ExecuteSlowStuff ,这个功能是你的 executeMyQuery 。最重要的部分是函数用来显示它正在进步的动作参数。

 专用共享功能ExecuteSlowStuff(BYVAL进步行动)作为整数
    昏暗的结果为0
    对于i = 0到10000
        结果+ = I
        Thread.sleep代码(500)
        进展()
    下一个

    返回结果
端功能
 

可以说,这项工作是由的DoSomething 按钮的点击启动。

 私人小组开始()处理的DoSomething.Click
    昏暗slowStuff =任务(整数).Factory.StartNew(
        ()的函数ExceuteSlowStuff(AddressOf Me.ShowProgress))
结束小组
 

您可能想知道其中 ShowProgress 的来源,那就是混乱位。

 私人小组ShowProgress()
    如果Me.Progress.InvokeRequired然后
        昏暗的交叉随着新的行动(AddressOf Me.ShowProgress)
        Me.Invoke(交叉)
    其他
        如果Me.Progress.Value = Me.Progress.Maximum然后
            Me.Progress.Value = Me.Progress.Minimum
        其他
            Me.Progress.Increment(1)
        结束如果

        Me.Progress.Refresh()
    如果最终
结束小组
 

请注意,由于 ShowProgress 可以从另一个线程中调用,它会检查跨线程调用。在这种情况下,它调用自身的主线程上。

I have this big SQL command that usually returns 20 000 - 100 000 rows of data. But as soon as i call the executeMyQuery function, the program hangs for a few seconds depending on how large the return is.

I only return one column.

How can I display a progress bar while this command is running?

Maybe in a Thread or something(I have NO experience with threads)

Here is my code(The arguments are sent from 3 different combobox.selectedItem) :

    Public Function executeMyQuery(dbname As String, colname As String, tblname As String)
    Try
        ListBox1.Items.Clear()
        If Not String.IsNullOrWhiteSpace(connString) Then
            Using cn As SqlConnection = New SqlConnection(connString)
                cn.Open()
                Using cmd As SqlCommand = New SqlCommand()
                    cmd.Connection = cn
                    Dim qry As String
                    qry = String.Format("select distinct [{0}] from {1}.dbo.{2} where [{0}] is not null", colname, dbname, tblname)
                    cmd.CommandText = qry
                    cmd.CommandTimeout = 0

                    Dim count As Integer
                    Using myReader As SqlDataReader = cmd.ExecuteReader()
                        While (myReader.Read())
                            count += 1
                            ListBox1.Items.Add(count.ToString & ". " & myReader.GetString(0))
                        End While
                    End Using
                End Using
            End Using
        End If
         cn.Close()
    Catch ex As Exception
        MsgBox("Error Occured : " & ex.Message)
        cn.Close()
    End 
End Function         

解决方案

Here is a cut down example of how to do Asychrounous Work with VB.Net 4.0.

Lets imagine you have a form that has the following imports,

Imports System.Windows.Forms
Imports System.Threading
Imports System.Threading.Tasks

That form has two controls

Private WithEvents DoSomthing As Button
Private WithEvents Progress As ProgressBar

Somewhere in your application we have a Function called ExecuteSlowStuff, this function is the equivalent of your executeMyQuery. The important part is the Action parameter which the function uses to show it is making progress.

Private Shared Function ExecuteSlowStuff(ByVal progress As Action) As Integer
    Dim result = 0
    For i = 0 To 10000
        result += i
        Thread.Sleep(500)
        progress()
    Next

    Return result
End Function

Lets say this work is started by the click of the DoSomething Button.

Private Sub Start() Handled DoSomething.Click
    Dim slowStuff = Task(Of Integer).Factory.StartNew(
        Function() ExceuteSlowStuff(AddressOf Me.ShowProgress))
End Sub

You're probably wondering where ShowProgress comes from, that is the messier bit.

Private Sub ShowProgress()
    If Me.Progress.InvokeRequired Then
        Dim cross As new Action(AddressOf Me.ShowProgress)
        Me.Invoke(cross)
    Else 
        If Me.Progress.Value = Me.Progress.Maximum Then
            Me.Progress.Value = Me.Progress.Minimum
        Else
            Me.Progress.Increment(1)
        End If

        Me.Progress.Refresh()
    End if
End Sub

Note that because ShowProgress can be invoked from another thread, it checks for cross thread calls. In that case it invokes itself on the main thread.