博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
VB.NET多线程入门
阅读量:6295 次
发布时间:2019-06-22

本文共 3836 字,大约阅读时间需要 12 分钟。

近期项目中遇到了一个处理速度慢阻塞用户界面操作的问题,因此想用多线程来解决。

在处理数据的循环中,新建线程,在新建的线程中处理数据。多线程同一时候处理数据,以此来达到加速的目的,使用户界面操作变得流畅。

在多任务操作系统中。我们能够在操作系统的协调下同一时候进行多个任务。各个任务以分时复用的形式来进行工作。

Windows操作系统通过进程ID来管理各进程。每一个进程至少包括一个线程。线程是进程中能够独立执行的程序片段。在主程序执行时,主程序能够启动线程。线程与主程序同一时候执行。

线程是系统中分时处理的最小单位,也就是说线程能够与主程序并行执行。參与同分时处理。线程有自己独立的栈处理数据。它在与主程序同一时候执行时能够共享主程序定义的变量、函数。仅仅有当线程执行结束才把控制权还给主程序。

创建线程最直接的方法是创建新的线程类实例,并使用Address Of语句为执行的过程传递托付。

可是这样的方法不能传递參数和返回值。

我们能够通过将在单独的线程中执行的过程包装到类或结构中。为它们提供參数,并使之能返回參数。

以下是一个新建线程的小demo:

Class TasksClass    Public StrArg As String    Public RetVal As Boolean    Public resultFlag As Boolean    Public Event ResultEvent(ByVal resultFlag As Boolean)    Public Sub SomeTask()        ' 将 StrArg 字段用作參数。        MessageBox.show("StrArg 包括字符串" & StrArg)        RetVal = True ' 设置返回參数的返回值。

End Sub End Class

Public Class Test    Private Sub Test_Load(sender As Object, e As EventArgs) Handles MyBase.Load        DoWork()    End Sub    ' 要使用类。请设置存储參数的属性或字段,    ' 然后。依据须要异步调用方法。

Sub DoWork() Dim Tasks As New TasksClass() Dim Thread1 As New System.Threading.Thread(AddressOf Tasks.SomeTask) Tasks.StrArg = "參数A" ' 设置用作參数的字段。 Thread1.Start() ' 启动新线程。 Thread1.Join() ' 等待线程 1 执行结束。

' 显示返回值。

MessageBox.show("线程 1 返回值" & Tasks.RetVal) End Sub End Class

这样一个线程就被新建出来了。

可是其实。创建过多的线程反而会影响性能。由于各个线程之间是分时复用的,操作系统须要在它们之间不断的切换。线程过多的时候,大量的时间消耗在线程切换上。

所以须要控制线程的数量。

如果我们仅仅新建10个线程,剩余的数据等待这10个线程中的某个结束,再继续新建线程处理数据。

使线程的总数一直保持在10个。

Public Class ThreadingObj    Public paper As WorkSpace    Public Sub ThreadingInsertPaper()        '多线程处理数据    End SubEnd ClassPrivate PaperList As List(Of WorkSpace) = New List(Of WorkSpace)Dim ThreadingList As List(Of System.Threading.Thread) = New List(Of System.Threading.Thread)
 
For Each paper In PaperList    '多线程处理PaperList    If ThreadingList.Count < 10 Then      '不到10个线程则继续新起线程          Dim ThreadingObject As New ThreadingObj          Dim ThreadingTask_1 As New System.Threading.Thread(AddressOf ThreadingObject.ThreadingInsertPaper)          ThreadingObject.paper = paper          ThreadingList.Add(ThreadingTask_1)          ThreadingTask_1.Start() ' 启动新线程。      Else          Dim goOnFlag As Boolean = False          '循环等待有线程结束          Do              If CheckThreadingStatus() Then                  '存在已完毕的线程                  If ThreadingList.Count <= 10 Then                      Dim ThreadingObject As New ThreadingObj                      Dim ThreadingTask_1 As New System.Threading.Thread(AddressOf ThreadingObject.ThreadingInsertPaper)                      ThreadingObject.paper = paper                      ThreadingList.Add(ThreadingTask_1)                      ThreadingTask_1.Start() ' 启动新线程。                      goOnFlag = True                  End If              Else                  '全部线程都在进行中              End If          Loop Until goOnFlag = True      End IfNext
Function CheckThreadingStatus() As Boolean    '返回True表示存在已完毕的线程    If ThreadingList.Count <= 10 Then        For Each ThreadingTaskItem In ThreadingList            'ThreadingTaskItem.IsAlive            If ThreadingTaskItem.IsAlive = False Then                ThreadingTaskItem.Abort()                ThreadingList.Remove(ThreadingTaskItem)                Return True            End If        Next    End If    Threading.Thread.Sleep(100)    If ThreadingList.Count <= 10 Then        For Each ThreadingTaskItem In ThreadingList            If ThreadingTaskItem.IsAlive = False Then                Return True            End If        Next    End If    Return FalseEnd Function

如果操作系统中有50个活跃的线程。如果我们的程序仅仅有一个线程。那么程序就占用了系统资源的五十分之中的一个。如果此时再多开一个线程,那么就占用了系统资源的2/51。我们的程序占用的资源越多。处理速度也就会更快一些。

由于各个线程之间是分时复用的,所以活跃的线程数量也会影响程序的效率。

有一种说法是2N + 2个线程数。是最有效率的。N是CPU的核数。

可是这一说法也一直存在争议。

我的測试结果例如以下(我的电脑是i7 4770 。四核八线程):

线程数 1 2 3 4 5 6 7 8 9 10 11 15
耗时 753 409 345 316 305 286 280 282 273 273 264 266

測试的结果有点奇怪。。

。。

可能跟一些其它的因素也有关系。

比方DB的状态,比方浏览网页对CPU的占用

转载地址:http://smpta.baihongyu.com/

你可能感兴趣的文章
esxi所连交换机划vlan导致vm不能通讯
查看>>
关于CE端口线路整改的建议
查看>>
如何禁止使用本地administrator进行共享连接
查看>>
用python解析html[SGMLParser]
查看>>
hive执行流程(3)-Driver类分析1Driver类整体流程
查看>>
Android开发学习笔记:对话框浅析
查看>>
Ajax学习-Ajax简介
查看>>
下载备忘:甘特图实现的代码
查看>>
Linux文本比较命令:diff
查看>>
redux-form的学习笔记二--实现表单的同步验证
查看>>
小评 XenServer 6.0功能
查看>>
Android中获取屏幕的宽和高
查看>>
ACL访问控制列表
查看>>
Lync Server 2010迁移至Lync Server 2013故障排错Part1:缺少McsStandalone.msi
查看>>
域控制器建立教程
查看>>
RHCE 学习笔记(20) ACL
查看>>
Django 和 Ajax 简介
查看>>
Qt的一个颜色选取按钮QColorButton
查看>>
perl 散列数组
查看>>
puppet之service管理
查看>>