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

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

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

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 Sub
End Class
Private 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 If
Next
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 False
End 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的占用

VB.NET多线程入门的更多相关文章

  1. java多线程入门学习(一)

    java多线程入门学习(一) 一.java多线程之前 进程:每一个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销.一个进程包括1--n个线程.     线程:同一类线程共享代码 ...

  2. Java多线程学习(一)Java多线程入门

    转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79640870 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...

  3. JavaSE_多线程入门 线程安全 死锁 状态 通讯 线程池

    1 多线程入门 1.1 多线程相关的概念 并发与并行 并行:在同一时刻,有多个任务在多个CPU上同时执行. 并发:在同一时刻,有多个任务在单个CPU上交替执行. 进程与线程 进程:就是操作系统中正在运 ...

  4. 【VB超简单入门】一、写在前面

    每本书的前面总得写点什么,到我这里也自然不能免俗,前言这东西“存在即合理”,所以就随便写一点咯~ 首先这本书是给从未接触过编程的童鞋准备的,由于我学识疏浅,对VB也只是一知半解所以也只能讲一点点最基础 ...

  5. (转载)Java多线程入门理解

    转载出处http://blog.csdn.net/evankaka 写在前面的话:此文只能说是java多线程的一个入门,其实Java里头线程完全可以写一本书了,但是如果最基本的你都学掌握好,又怎么能更 ...

  6. c++标准库多线程入门

    从c++ 11开始,语言核心和标准库开始引入了对多线程的原生支持.如下所示: int doSth(char c) { default_random_engine dre(c); uniform_int ...

  7. C++面向对象多线程入门

    第1节   背景 为了更好的理解多线程的概念,先对进程,线程的概念背景做一下简单介绍. 早期的计算机系统都只允许一个程序独占系统资源,一次只能执行一个程序.在大型机年代,计算能力是一种宝贵资源.对于资 ...

  8. Java多线程入门知识点梳理

    前言 在多核时代,高并发时代,对系统并行处理能力有很高要求.多线程就是这个时代最好的产物.通过使用多线程可以增强系统并行处理能力,提高CPU资源的有效利用:从而提高系统的处理能力.常见应用场景如:多窗 ...

  9. c++11 多线程入门教程(一)

    原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/10945309.html 最近在找c++服务端开发的实习(大佬们有推荐吗QAQ..),恰好写了一 ...

随机推荐

  1. 轻轻的我走了,正如我轻轻的来——Duilib无焦点窗体的实现

    在Windows编程中,我们已经习惯了一个窗体从创建到显示并获得焦点. 我们总感觉一个窗体创建出来获得焦点是理所理所当然的.一个窗体仅仅要显示就必须获得焦点.一个新窗体显示时.会收到到WM_SETFO ...

  2. JDBC 关于大文本数据

    大文本数据Clob,在不同的数据库中类型名不一致,有的是text格式,有的是clob,还有其他一些格式   package test; import java.io.BufferedReader; i ...

  3. PLSQL Split分割字符串

    系统自带的split,使用起来方便,但是如果字符串太长,可能会出现异常,这里,我自己写了一个也是该名字,放在自己的包中,引用的时候带包名就好了. --系统自带的函数 /*CURSOR cur_temp ...

  4. 快速激活JetBrains系列产品

    本篇文章由:http://xinpure.com/quickly-activate-the-jetbrains-products/ lanyus.com 域名已被全面封杀,大家可以到 http://i ...

  5. 快速掌握Gif动态图实现代码

    版权声明:本文为博主原创文章,未经博主允许不得转载. 前言:Gif一种动态图片,网上有很多制作这个的工具,包括PS都有,但作为一名程序员,我觉得如果自己通过编写代码把它实现,不但是对代码的掌握与复习, ...

  6. ArcGis10.0常见错误

    1. 问题:  Arcgis10.0 组件初始化失败 解决方法:  ESRI.ArcGIS.RuntimeManager.BindLicense(ESRI.ArcGIS.ProductCode.Eng ...

  7. /usr/lib64改名字风波

    注:本文描述请勿模仿,仅限万一遇到这种情况一试. 一不小心做了一个操作: cd /usr mv lib64 lib64-bak 然后奇异的发现: cp不能用了!ls也不能用了…… 提示信息如下: -b ...

  8. CentOS 之 Supervisor

    CentOS 之 Supervisor supervisor是一个Linux上用来管理程序后台运行的工具,支持程序的自启动,挂掉重启,日志等功能.可配置程序随系统启动,并支持挂掉重启,增强程序稳定性. ...

  9. Android7.0 MessageQueue

    Android中的消息处理机制大量依赖于Handler.每一个Handler都有相应的Looper,用于不断地从相应的MessageQueue中取出消息处理. 一直以来,觉得MessageQueue应 ...

  10. char类型到底是有符号还是无符号

    根据c标准,char类型到底是有符号整数类型还是无符号整数类型,这取决于c实现,也就是c编译器的作者的想法:( 那么,如何快速的编写一个检测程序,查看当前编译器如何对char进行定义? #includ ...