VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > VB.net教程 >
  • VB.net WinForm如何写一个分线程进度条

首先, 我们先来看一个长耗时过程

    Private Sub ValueTest()       
        For i As Integer = 0 To 100
            ProgressBar1.Value = i 
            Threading.Thread.Sleep(1000)
        Next
    End Sub
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

我们会发现,在100时间内,窗体无法被移动,进度条也不会移动(win10的UI可以移动,但任然看起来很卡),等循环完毕后进度条突然就满了。 懂UI窗体运行原理的都知道,程序的主线程不仅仅要处理我们写的代码,还要刷新UI的界面。当在处理长耗时过程时,UI界面也会被“锁死”,直到过程被执行完毕。 有些懂线程委托的小朋友就要说了,用分线程委托嘛,例如这样:

  Private Sub ValueTest_Thread()
        For i As Integer = 0 To 100
            ChangePBValue(i, ProgressBar1)
            Threading.Thread.Sleep(1000)
        Next
    End Sub
    Private Sub ChangePBValue(_Value As Integer, ByRef _PB As ProgressBar)
        If _PB.InvokeRequired = True Then
            _PB.BeginInvoke(New D_ChangePBValue(AddressOf ChangePBValue), _Value, _PB)
        Else
            _PB.Value = _Value
        End If
    End Sub
    Private Delegate Sub D_ChangePBValue(_Value As Integer, ByRef _PB As ProgressBar)
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        Dim NT As New Threading.Thread(AddressOf ValueTest_Thread)
        NT.Start()
    End Sub
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

萌新们表示看起来很困难,我这里不过多解释怎么创建分线程了,自己百度一下跨线程更新控件方法与原理。 我给大家说一下分线程窗体的调用方法

    Private Sub ValueTest_ThreadForm()
        ThreadPBManger.Start("我想表达点什么呢???")
        For i As Integer = 0 To 100
            ThreadPBManger.SetValue(i)
            Threading.Thread.Sleep(100)
        Next
        ThreadPBManger.Stop()
    End Sub
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

好像很简单啊,这样就可以在主线程完全卡死的情况下也能在进度条中显示进度了,还能报告在做什么内容,好神奇,但是ThreadPBManger是什么鬼?

Public Module ThreadPBManger
    Dim NF_PB As F_PB
    Public Sub Start(ShowStr As String)
        Dim NT As New Threading.Thread(AddressOf Start_thread)
        NT.Start(ShowStr)
    End Sub
    Private Sub Start_thread(ShowStr As String)
        NF_PB = New F_PB
        NF_PB.Text = ShowStr
        Application.Run(NF_PB)
    End Sub
    Public Sub SetValue(Value As Integer)
        If IsNothing(NF_PB) Then Return
        If NF_PB.IsDisposed Then Return
        ChangePBValue(Value, NF_PB.ProgressBar1)
    End Sub
    Private Delegate Sub D_Stop()
    Public Sub [Stop]()
        If IsNothing(NF_PB) Then Return
        If NF_PB.IsDisposed Then Return
        If NF_PB.InvokeRequired Then
            NF_PB.Invoke(New D_Stop(AddressOf [Stop]))
        Else
            NF_PB.Dispose()
        End If
    End Sub

#Region "委托更新PB"
    Public Sub ChangePBValue(_Value As Integer, ByRef _PB As ProgressBar)
        If _PB.InvokeRequired = True Then
            _PB.BeginInvoke(New D_ChangePBValue(AddressOf ChangePBValue), _Value, _PB)
        Else
            _PB.Value = _Value
        End If
    End Sub
    Private Delegate Sub D_ChangePBValue(_Value As Integer, ByRef _PB As ProgressBar)
#End Region
End Module
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

源码位置 https://download.csdn.net/download/meiren777/10762052

知识点 Delegate,线程委托,BeginInvoke,InvokeRequired

重点解释

  • Application.Run:在当前线程上开始运行标准应用程序消息循环,并使指定窗体可见。以该模式打开窗体后,该线程窗体将持续响应消息循环,该线程只会随着窗体的关闭而关闭。一个线程只有存在一个消息循环。当前执行位置将会停止在此,当制定窗体关闭后,继续执行后面的代码。

PS

  • 实际使用过程中,需要小伙伴们美化窗体,并添加更多的Try Catch来处理具体的异常。
  • 有趣的是Devexpress提供了SplashScreenManager提供了完整的线程进度窗体解决方案,我们叫它飞溅窗体。基础版使用相对简单,但要使用自定义窗体其难度非常高,后面我开文章教大家如何使用Devexpress的控件(想想脑壳疼,好大的项目啊!)


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/meiren777/article/details/83686131


相关教程