欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

VB.NET多线程入门

程序员文章站 2022-04-14 10:09:05
最近项目中遇到了一个处理速度慢堵塞用户界面操作的问题,因此想用多线程来解决。 在处理数据的循环中,新建线程,在新建的线程中处理数据。多线程同时处理数据,以此来达到加速的目的,使用户界面操作变得流畅。...

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

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

在多任务操作中,我们可以在操作系统的协调下同时进行多个任务。各个任务以分时复用的形式来进行工作。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