ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

VB.net WinForm如何写一个分线程进度条

2021-02-10 12:59:23  阅读:190  来源: 互联网

标签:VB End Sub 进度条 Value PB 线程 NF


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

Private Sub ValueTest()       
    For i As Integer = 0 To 100
        ProgressBar1.Value = i 
        Threading.Thread.Sleep(1000)
    Next
End Sub

我们会发现,在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

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

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

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

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

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

重点解释

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

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

标签:VB,End,Sub,进度条,Value,PB,线程,NF
来源: https://blog.csdn.net/chinaherolts2008/article/details/113781205

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有