iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >C#异步多线程中Thread的示例分析
  • 100
分享到

C#异步多线程中Thread的示例分析

2023-06-25 17:06:25 100人浏览 泡泡鱼
摘要

这篇文章给大家分享的是有关C#异步多线程中Thread的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Thread api这里对 Thread 的一些常用 API 进行介绍,使用一些案例进行说明。由于 T

这篇文章给大家分享的是有关C#异步多线程中Thread的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

Thread api

这里对 Thread 的一些常用 API 进行介绍,使用一些案例进行说明。由于 Thread 的不可控与效率问题,Thread 现在已经不常用了,这里介绍一些 API ,想更深入的同学可以继续研究研究。

Instance

首先看 Thread 的构造函数,有 ThreadStart 、ParameterizedThreadStart 、maxStackSize 类型的参数,这三个常用的也就 ThreadStart ,其他两个可以作为了解。

C#异步多线程中Thread的示例分析

分别 F12 查看 ThreadStart、ParameterizedThreadStart ,可以看到 ThreadStart 是无参数类型的委托、ParameterizedThreadStart 是有参数类型的委托。maxStackSize 是指定线程占用的最大内存数。

C#异步多线程中Thread的示例分析

C#异步多线程中Thread的示例分析

C#异步多线程中Thread的示例分析

接着我们创建一个简单的案例,启动一个线程,模拟做一些任务行。如下代码

Console.WriteLine($"Main 方法开始,ThreadId:{Thread.CurrentThread.ManagedThreadId}");ThreadStart threadStart = () =>{    Console.WriteLine($"Task Start ThreadId:{Thread.CurrentThread.ManagedThreadId}");    // 做一些任务    Console.WriteLine($"Task End ThreadId:{Thread.CurrentThread.ManagedThreadId}");};Thread thread = new Thread(threadStart);thread.Start();Console.WriteLine($"Main 方法结束,ThreadId:{Thread.CurrentThread.ManagedThreadId}");Console.ReadLine();

C#异步多线程中Thread的示例分析

启动程序,可以看到线程 1(主线程),没有等待线程 3(子线程)执行完成匿名方法内的任务,再执行 Main 结束这段代码。如果使用的是 winform 是不会卡界面的。

这就是异步多线程,异步在于线程 1 并没有等待线程 3 执行完成任务,再执行线程 1 内的下一行,而是让线程 3 在不影响线程 1 执行任务的情况下执行,这就是异步。多线程在于我们启动了一个线程 3(子线程),在 Main 方法由线程1(子线程)与线程 3(主线程)一起完成 Main 方法内的代码,这就是多线程。

C#异步多线程中Thread的示例分析

说到委托可会有小伙伴发出疑问,为啥不用 Action ?

因为在这个版本还没有 Action、Func,这是在 .net 3.0 时代的产物,Action、Func 的出现就是为了统一,也是为了解决此类问题。

dotnet 框架,也建议最好使用 Action、Func,所以,在这使用 Action 是不可以的。如下

Console.WriteLine($"Main 方法开始,ThreadId:{Thread.CurrentThread.ManagedThreadId}");Action action = () =>{    Console.WriteLine($"Task Start ThreadId:{Thread.CurrentThread.ManagedThreadId}");    // 做一些任务    Console.WriteLine($"Task End ThreadId:{Thread.CurrentThread.ManagedThreadId}");};ThreadStart threadStart = action;Thread thread = new Thread(threadStart);thread.Start();Console.WriteLine($"Main 方法结束,ThreadId:{Thread.CurrentThread.ManagedThreadId}");Console.ReadLine();

C#异步多线程中Thread的示例分析

Suspend、Resume

Suspend 挂起、Resume 唤醒,这两个是一对相互对应的 API,使用时这两个容易产生死,其实在实际中也是不应该使用的,.NET 框架已经抛弃了,说的很清楚了。

为什么会死锁呢?比如你开启了一个子线程 01,对 A 文件进行读写操作,此时你对子线程 01 进行了挂起。当你另外一个线程对 02 A 文件进行操作时,此时提示会 A 文件被占用,就行形成死锁。

C#异步多线程中Thread的示例分析

C#异步多线程中Thread的示例分析

Abort、ResetAbort

Abort 销毁,很多人在使用,这种是抛异常方式,使子线程销毁结束。这个功能也比较鸡肋,Abort 时子线程并不能立即停止,往往会有一些延迟,那这个销毁有时也不能达到我们可控的效果。

比如,在一个方法内开了一个子线程进行数据计算,但执行的时间太长了,我们等待了 5000 ms,此时 Abort 子线程,是不能立马让子线程停止计算,而是可能要等一会才能结束子线程。

比如,发出的动作,可能收不回来。查询数据库来说,当一个查库命令发送到数据库,我们在C# 执行了 Abort,但查库这个命令是收不回来的,因为他是在数据库层面,当数据库查询完成只是没有接收响应的线程罢了。

C#异步多线程中Thread的示例分析

Abort 不建议使用,如果使用,一定要 try catch 一下。

Console.WriteLine($"Main 方法开始,ThreadId:{Thread.CurrentThread.ManagedThreadId}");ThreadStart threadStart = () =>{    Console.WriteLine($"Task Start ThreadId:{Thread.CurrentThread.ManagedThreadId}");    // 做一些任务    Console.WriteLine($"Task End ThreadId:{Thread.CurrentThread.ManagedThreadId}");};Thread thread = new Thread(threadStart);thread.Start();try{    thread.Abort(); // 销毁,方式是抛异常,不一定及时}catch (Exception ex){    //Thread.ResetAbort(); // 取消异常}Console.WriteLine($"Main 方法结束,ThreadId:{Thread.CurrentThread.ManagedThreadId}");Console.ReadLine();

C#异步多线程中Thread的示例分析

Suspend、Resume、Abort 这几个方法不建议使用,操作线程暂停、销毁或者其他操作都是不可控的,应为线程本身是操作系统的, CPU 分时分片会按照自己的规则进行运行,此时已经不是程序可以进行控的了。 既然设计了 Thread 不可能一无是处,接下来我们说些有用的

Join

线程等待 ,Join 可以一直等,也可以设置超时,超时就是等待一定时间,就不等了。等待的过程中主线程处于闲置状态等着子线程完成任务。如果是 winfORM 是会卡界面的,主线程等待也是一种工作。

例如:threadStart 我们模拟任务耗时 5 秒,在 thread.Start() 任务开始后,使用 thread.Join() 等着子线程完成工作

Console.WriteLine($"Main 方法开始,ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");ThreadStart threadStart = () =>{    Console.WriteLine($"Task Start ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");    // 做一些任务    Thread.Sleep(5 * 1000); // 模拟任务耗时 5 秒    Console.WriteLine($"Task End ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");};Thread thread = new Thread(threadStart);thread.Start();thread.Join();Console.WriteLine($"Main 方法结束,ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");Console.ReadLine();

启动程序,可以看到是我们想要的结果(与同步执行一样),主线程 1 一直等着 子线程 3 完成执行的任务。如果是 winform 是会卡界面的,虽然 thread.Join() 主线程 1 会等着子线程 3 完成工作,但主线程 1 等着也是一种工作。

C#异步多线程中Thread的示例分析

接着我们看下超时等待,Join 的重载方法

例如:threadStart 我们模拟任务耗时 5 秒,在 thread.Start() 任务开始后,使用 thread.Join(3*1000) ,让主线程最多等子线程 3 秒,如果 3 秒子线程还未完成任务,就不等待了

Console.WriteLine($"Main 方法开始,ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");ThreadStart threadStart = () =>{    Console.WriteLine($"Task Start ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");    // 做一些任务    Thread.Sleep(5 * 1000); // 模拟任务耗时 5 秒    Console.WriteLine($"Task End ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");};Thread thread = new Thread(threadStart);thread.Start();thread.Join(3 * 1000);Console.WriteLine($"Main 方法结束,ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");Console.ReadLine();

启动程序,主线程 1 开始任务,子线程 3 也开始任务,当子线程执行 3 s 后(期间主线程 1 在等待),主线程 3 开始执行任务了。

C#异步多线程中Thread的示例分析

注意:thread.Join(n * 1000) 并不是一定会等待那么长时间,而是最多等待,期间子线程任务执行完成后,就不等待了。

例如:threadStart 任务方法模拟 5 s,thread.Join(7 * 1000) 主线程等待 7 s

Console.WriteLine($"Main 方法开始,ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");ThreadStart threadStart = () =>{    Console.WriteLine($"Task Start ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");    // 做一些任务    Thread.Sleep(5 * 1000); // 模拟任务耗时 5 秒    Console.WriteLine($"Task End ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");};Thread thread = new Thread(threadStart);thread.Start();thread.Join(7 * 1000);Console.WriteLine($"Main 方法结束,ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");Console.ReadLine();

C#异步多线程中Thread的示例分析

ThreadState

线程状态,ThreadState 也可以做线程等待,等待的过程中主线程处于闲置状态等着子线程完成任务。如果是 winform 是会卡界面的,主线程等待也是一种工作。

Console.WriteLine($"Main 方法开始,ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");ThreadStart threadStart = () =>{    Console.WriteLine($"Task Start ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");    // 做一些任务    Thread.Sleep(5 * 1000); // 模拟任务耗时 5 秒    Console.WriteLine($"Task End ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");};Thread thread = new Thread(threadStart);thread.Start();while (thread.ThreadState != ThreadState.Stopped){    Thread.Sleep(200); // 当前线程休息 200 毫秒}Console.WriteLine($"Main 方法结束,ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");Console.ReadLine();

C#异步多线程中Thread的示例分析

Sleep

线程暂停,Sleep 当前线程暂停。如果是 winform 是会卡界面的,当 Sleep 时,CPU 分片就交出去了,主线程并不在工作状态。

Console.WriteLine($"Main 方法开始,ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");Thread.Sleep(5 * 1000); // 模拟任务耗时 5 秒Console.WriteLine($"Main 方法结束,ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");Console.ReadLine();

C#异步多线程中Thread的示例分析

IsBackground

是否是后台线程,当实例 Thread 时,默认是前台线程(IsBackground == false )。前台线程一定要任务完成,才会让进程退出。后台线程(IsBackground == true)会随着进程的结束而结束,无论子线程任务是否完成。

前台线程,意思也就是,当我们启动一个程序,当关闭程序时,如果还有子线程执行任务,当前进程是不会退出的,会等待着子进程将任务执行完成,也就是会阻止进程结束,反之亦然。

例如:前台线程,启动控制台后,主线程执行完任务后,会等待子线程任务完成(5s)后,窗口才会被关闭

static void Main(string[] args){    Console.WriteLine($"Main 方法开始,ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");    ThreadStart threadStart = () =>    {        Console.WriteLine($"Task Start ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");        // 做一些任务        Thread.Sleep(5 * 1000); // 模拟任务耗时 5 秒        Console.WriteLine($"Task End ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");    };    Thread thread = new Thread(threadStart);    thread.Start();    while (thread.ThreadState != ThreadState.Stopped)    {        Thread.Sleep(200); // 当前线程休息 200 毫秒    }    Console.WriteLine($"Main 方法结束,ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");}

例如:后台线程,启动控制台后,主线程任务执行完毕后,窗口会立马被关闭

static void Main(string[] args){    Console.WriteLine($"Main 方法开始,ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");    ThreadStart threadStart = () =>    {        Console.WriteLine($"Task Start ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");        // 做一些任务        Thread.Sleep(5 * 1000); // 模拟任务耗时 5 秒        Console.WriteLine($"Task End ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");    };    Thread thread = new Thread(threadStart);    thread.IsBackground = true;    thread.Start();    Console.WriteLine($"thread IsBackground:{thread.IsBackground},DateTime:{DateTime.Now.ToLongTimeString()}");    Console.WriteLine($"Main 方法结束,ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");}

Priority

线程可以设置优先级,当线程从高到低分配了优先级,在向 CPU 申请线程时会优先分配。但是这个功能也比较鸡肋,对于 CPU 而言,当他们同时过来,只是会为优先级高的先分进行分片,但优先级低的并不是不会分配,也不代表优先级高的就会先执行完成,这也取决执行的任务量。其实优先级也没什么用,多线程本来就是无序的。

Console.WriteLine($"Main 方法开始,ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");ThreadStart threadStart = () =>{    Console.WriteLine($"Task Start ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");    // 做一些任务    Thread.Sleep(5 * 1000); // 模拟任务耗时 5 秒    Console.WriteLine($"Task End ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");};Thread thread = new Thread(threadStart);thread.Priority = ThreadPriority.Highest;// CPU 会先执行,不代表 Highest 就最优先thread.Start();Console.WriteLine($"thread IsBackground:{thread.IsBackground},DateTime:{DateTime.Now.ToLongTimeString()}");Console.WriteLine($"Main 方法结束,ThreadId:{Thread.CurrentThread.ManagedThreadId},DateTime:{DateTime.Now.ToLongTimeString()}");

感谢各位的阅读!关于“C#异步多线程中Thread的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

--结束END--

本文标题: C#异步多线程中Thread的示例分析

本文链接: https://www.lsjlt.com/news/306207.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C#异步多线程中Thread的示例分析
    这篇文章给大家分享的是有关C#异步多线程中Thread的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Thread API这里对 Thread 的一些常用 API 进行介绍,使用一些案例进行说明。由于 T...
    99+
    2023-06-25
  • C#中异步多线程的示例分析
    这篇文章主要介绍C#中异步多线程的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!进程、线程1. 进程首先了解,什么是线程 即一个应用程序运行时,占用资源的综合是一个进程。Windows 任务管理器里面可以看到...
    99+
    2023-06-25
  • C#多线程中线程同步的示例分析
    这篇文章将为大家详细讲解有关C#多线程中线程同步的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、前言我们先来看下面一个例子:using System;using Syste...
    99+
    2023-06-29
  • c#中异步编程的示例分析
    这篇文章给大家分享的是有关c#中异步编程的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、什么算异步?  广义来讲,两个工作流能同时进行就算异步,例如,CPU与外设之间的工作流就是异步的。在面向服务的系...
    99+
    2023-06-14
  • C#异步编程的示例分析
    小编给大家分享一下C#异步编程的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!异步编程在处理并发方面被使用的越来越多,之所以说上面一句话,是为了区分多线程...
    99+
    2023-06-17
  • JS中异步和单线程的示例分析
    这篇文章主要介绍了JS中异步和单线程的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。单线程但是我们在开发中,遇到请求网络,或者定时任务的时候,如果等待网络请求结束或者...
    99+
    2023-06-15
  • C#多线程Thread使用示例详解
    本文实例为大家分享了C#多线程Thread使用的示例代码,供大家参考,具体内容如下 多线程: 线程生命周期状态图: C#线程优先级(概率高低): 基本使用示例: usin...
    99+
    2024-04-02
  • C# 异步多线程入门到精通之Thread篇
    上一篇:C# 异步多线程入门基础 下一篇:C# 异步多线程入门到精通之ThreadPool篇 Thread API 这里对 Thread 的一些常用 API 进行介绍,使用一些案例进...
    99+
    2024-04-02
  • C#异步通信的示例分析
    这篇文章主要为大家展示了“C#异步通信的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C#异步通信的示例分析”这篇文章吧。C#异步通信概念及应用的认识首先让我们来看看:在网络编程中运用S...
    99+
    2023-06-17
  • java中多线程的示例分析
    这篇文章主要介绍了java中多线程的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。java多线程并发与并行:并行: 指两个或多个事件在同一时刻发生 ( 同时发生 ) ...
    99+
    2023-06-20
  • iOS中多线程的示例分析
    这篇文章给大家分享的是有关iOS中多线程的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、iOS的三种多线程技术NSThread–优点:NSThread 比其他两个轻量级,使用简单–缺点:需要自己管理线...
    99+
    2023-06-21
  • JavaScript中异步编程的示例分析
    这篇文章给大家分享的是有关JavaScript中异步编程的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。目的提升开发效率,编写易维护的代码引子问题请求时候为什么页面卡死??$.ajax({ &n...
    99+
    2023-06-15
  • Promise中异步编程的示例分析
    这篇文章主要介绍Promise中异步编程的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!实例如下所示://1.解决异步回调问题 //1.1 如何同步异步请求 //如...
    99+
    2024-04-02
  • C++多线程中的线程同步与互斥量实例分析
    本篇内容介绍了“C++多线程中的线程同步与互斥量实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!线程同步#include &...
    99+
    2023-06-30
  • Java多线程同步问题的示例分析
    这篇文章主要介绍Java多线程同步问题的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!简单了解下在操作系统中进程和线程的区别:  进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开...
    99+
    2023-05-30
    java
  • Node.js中的异步编程的示例分析
    Node.js中的异步编程的示例分析,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。异步编程概述曾经的单线程模型在...
    99+
    2024-04-02
  • JavaScript中异步的示例分析
    这篇文章将为大家详细讲解有关JavaScript中异步的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、异步解决方案的进化史JavaScript的异步操作一直是...
    99+
    2024-04-02
  • Python多线程的示例分析
    这篇文章将为大家详细讲解有关Python多线程的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。线程相对进程来说是“轻量级”的,操作系统用较少的资源创建和管理线程。程序中的线程在相同的内存空间中执行...
    99+
    2023-06-17
  • Java程序中多线程的示例分析
    这篇文章主要介绍了Java程序中多线程的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。  为什么会排队等待?  下面的这个简单的 Java 程序完成四项不相关的任务。...
    99+
    2023-06-03
  • python中asyncio异步编程的示例分析
    这篇文章将为大家详细讲解有关python中asyncio异步编程的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1.   想学asyncio,得先了解协程携程的意义:计算型的操...
    99+
    2023-06-14
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作