c# 线程的等待(堵塞)

2023-05-16

 

这里我要强调一个概念,

 多线程是多线程,

异步编程是异步编程

这两个是有区别的概念;

我可以说多线程天生就要异步的特点;但你不能说多线程成就等同于我们的异步编程;

根不能说异步编程就是我们的多线程。这里不要搞混淆了;

再net中的进化如下:

多线程:Thread =>ThreadPool=> Task

异步编程:BenginInvokeXXX EndInvokeXXX IAsyncResult=> async await (这里面配合着Task的使用)(基于任务的异步模式 (TAP) 时来使用异步操作)

好接下来,再来总结我们的线程(任务)的等待。

总结:

方法一:Thread.Sleep(),这个要预估,等待的时间应该大于我们的子线程执行的时间。

方法二:当然就是我们最常用的Join() 方法了,堵塞当前调用子线程成的方法,直到我们的子线程执行完毕。

方法二:主线程轮训子线程(这个是基于我们的IasyncResult 编程模式的,及时传说中的beginxxxx  endxxxx这种模式)

方法三:采用通知的方法就是我们的EevntWaitHanld = new AutoRestEevnt(false),然后waitOne 和 Set 的方式来进行的,效果非常好滴呀;

方法四:我把它命名为偏方:就是利用独占锁的机制,当子线程用完锁之后,释放,让给我们的主线程,前提是要确保我们的子线程先得到锁;

方法五:这个就是基于我们的Task的wait方法;

这里我给出一些,练习的demo,仅供参考使用;


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication13
{
    //我们把它叫做等待子线程,或者,等待子线程一定的时间;
    //最原始的是使用 waitEevnt的方法;我们甚至可以用 poll的方式;
    //还有基于事件编程的回调方式;

    
    public class Person
    {

    }
    class Program
    {
        //evnet wait handle
        //该方法也可以用来进行线程的同步滴呀;
        public static object locker = new object();
        public static EventWaitHandle handler = new AutoResetEvent(false);

        public static void Eat()
        {
            Thread.Sleep(3000);
        }

        public static void Eat_WithSet()
        {
            Thread.Sleep(3000);

            handler.Set(); //子线程发出做完实行的信号;
        }

        public static void Eat_WithLock()
        {
            Console.WriteLine("枷锁开始");
            lock (locker)
            {
                Thread.Sleep(3000);   //假设,我们这里有很多的是事情要做的呀;
                //效果非常好;
            }
            Console.WriteLine("枷锁释放");
        }

        public static void Eat_Loop()
        {

            for (int i = 0; i < 10; i++)
            {
                Thread.Sleep(1000);
                Console.WriteLine("");
            }

        }

        //那么这个方法就不能为空了

        public static  void Eat_Wait()
        {
            for (int i = 0; i < 10; i++)
            {
                Task.Delay(1000).Wait();
                Console.WriteLine("");
            }

        }

        public static void TestJoin()
        {

            Console.WriteLine("main start");

            Thread thread = new Thread(Eat);
            thread.Start();
            //给我等着;
            Console.WriteLine("主线程先做点其他事情;");
            //这我们我们可以直接用线程自带的方法;
            thread.Join();
            Console.WriteLine("好了,子线程事情做完了..");
            Console.WriteLine("main end");
            Console.ReadLine();

        }

        public static void Test_Set()
        {

            Console.WriteLine("main start");

            Thread thread = new Thread(Eat_WithSet);
            thread.Start();
            //给我等着;
            Console.WriteLine("主线程先做点其他事情;");
            handler.WaitOne();
            Console.WriteLine("好了,子线程事情做完了..");
            Console.WriteLine("main end");
            Console.ReadLine();

        }

        public static void Test11()
        {

            Console.WriteLine("main start");

            Thread thread = new Thread(Eat_WithSet);
            thread.Start();
            //给我等着;
            Console.WriteLine("主线程先做点其他事情;");
            handler.WaitOne(TimeSpan.FromSeconds(3));

            //注意这里,一点 waitone 和 task.wait 如果都指定了 等待的时间;
            //如果子线程在指定的时间内没有做完时间,那么我们就开始了主线程的方法;
            //这里并没有真正的取消线程;
            //问题又来了,如果去取消子线程呢;这个......

            Console.WriteLine("好了,不堵塞,主线程了,");
            Console.WriteLine("main end");
            Console.ReadLine();

        }
        //偏方
        public static void Test_Lock()
        {

            Console.WriteLine("main start");
            Thread thread = new Thread(Eat_WithLock);
            thread.Start();
            //给我等着;
            Console.WriteLine("主线程先做点其他事情;");
            
            //如果是单线层的话,我还是使用一点偏方;
            //那就是我们的lock方法滴呀;
            Thread.Sleep(20);//为了让子线程得到锁,我们这里估计sleep一下了
            //所以尼玛的叫偏方了;
            lock (locker)
            {
                //当然这种方式,就是完全出去一种四等的状态;
                //等待另外一个线程释放锁;
                Console.WriteLine("这个表示我们的另外一个线程执行完毕了;");
            }
            Console.ReadLine();

        }

        //如果要取消原来的方法的话,还得到原来的的方法去操作,整的是麻烦的一件事情;
        //不过有我们的Task 就方便多;;

        public static void Test_Task()
        {
            //task的取消就相对简单的多了;
            Console.WriteLine("main start");
            Task task = Task.Run(()=>Eat_Wait());

            Console.WriteLine("mian do something.then wait task");

           // task.Wait();  //默认情况下,它会等待task执行完毕;

            task.Wait(TimeSpan.FromSeconds(3));//在这里只能等待三秒,三秒只有,就不堵塞我们的主线程;
            //这里这的注意的事情是,等待不等于取消哦;
            //这一点是相对非常关键的啦;

            //先一节我们再来略略线程的取消啦滴呀;

            Console.WriteLine("task completed...");

            Console.WriteLine("main end");

            Console.ReadLine();

        }

   
        static void Main(string[] args)
        {

            //Test();
            //Test1();
            //Test11();
            //Test_Lock();
            //Test_Task();

        }
    }
}  

//这里我再来演示一个set 之后,通知多个线程的实例,或则理解成为广播是似的传递消息;

或则:多个线程在等待某一个线程的信号;

  to do 

 

 线程只有不断的去判断他的isalive属性;

异步编程则可以使用的轮训的回调的方式;  如果你的主线程一直等待,那么 尼玛的就叫异步编程了;


        public static void Test_IsAlive()
        {

            //Eat_Loop
            Console.WriteLine("main start");

            Thread thread = new Thread(Eat_Loop);
            thread.Start();
            Console.WriteLine("mian do something.then wait task");

            while (thread.IsAlive)
            {
                Thread.Sleep(100);
                Console.WriteLine("子线程还在zuoshiser");
            }

            Console.WriteLine("子线程把事儿做完了!");

            Console.WriteLine("mian end");
        }

        public static int CountInfo(int x)
        {
            Thread.Sleep(5000);
            return x+100;
        }

        public static void Test_IsComplete()
        {
            //异步编程了
            Func<int, int> fn = CountInfo;
            IAsyncResult actionResult = fn.BeginInvoke(100, CountInfoCallback, null); //既没有回调,也没有参数这样的方法不太正常;

           while (!actionResult.IsCompleted)
           {
               Thread.Sleep(100);
               Console.WriteLine("子线程还在zuoshiser");
           }
            //做完之后 记得endinvoke;
            int result= fn.EndInvoke(actionResult);
            //这样就可以得到我们的结果;

           //在这里结束,也可以在回调方法中结束 endInvoek;


        }

        static void CountInfoCallback(IAsyncResult iar)
        {
            Console.WriteLine("这里是回调....");

            AsyncResult ar = (AsyncResult)iar;

            Func<int, int> del = (Func<int, int>)ar.AsyncDelegate;
            var result = del.EndInvoke(iar);

            //总的的来说,就是我们的采用回调和轮训的两种方式;
            //来实现我们的异步编程的实现;
            //不过好在,现在我们又了 async 和await 基于task的异步编程;
            //那效果,整的是杠杠的,效果是非常好滴呀;

        }  

好了就到这里;。

 

 

转载于:https://www.cnblogs.com/mc67/p/7467550.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c# 线程的等待(堵塞) 的相关文章

  • github,源码,高仿 直播

    仿花田 xff1a 相亲网站 意中人 已在GitHub上开源 从头开始写一款开源app上线 相互学习 SlideMenuControllerSwift swift实现双侧边栏菜单 StepView github 物流信息 iOS 常用控件集
  • 一文搞懂RAM、ROM、SDRAM、DRAM、DDR、flash等存储介质

    一文搞懂RAM ROM SDRAM DRAM DDR flash等存储介质 存储介质基本分类 xff1a ROM和RAM RAM xff1a 随机访问存储器 Random Access Memory xff0c 易失性 是与CPU直接交换数
  • IDEA解决从git上clone代码没有maven依赖的问题

    首先 xff0c 从git上拉取代码 xff1a 我们将新clone下来的项目打开 xff0c 可以发现在git上原本是maven项目的工程 xff0c 没有了maven的结构 xff1a 要解决这个问题 xff0c 我们需要关闭这个项目
  • python plt画图横纵坐标0点重合

    coding utf 8 import numpy as np import matplotlib mlab as mlab import matplotlib pyplot as plt from scipy import optimiz
  • Fiji-imageJ 无法打开

    可能的原因是文件的路径包含中文名称 转载于 https www cnblogs com cmyg p 11408207 html
  • The type name or alias SqlServer could not be resolved.Please check your configuration

    The type name or alias SqlServer could not be resolved Please check your configuration file 检查一下Config文件中包含的dll再dubug文件夹
  • 总结记录一下如何统计CPU使用情况、磁盘利用率

    一 cpu使用率 可以使用 proc stat命中查看 举例 xff1a cat proc stat grep cpu cpu 1391321772 178 2524194226 33711208592 1046582 6540 38867
  • LCD1602屏幕简介(全网最详细教程)

    目录 1 接线说明 2 LCD1602显示原理 3 LCD1602时序分析 4 LCD1602显示一个字符 5 LCD1602显示一行 1 接线说明 第1引脚 xff1a GND为电源地 第2引脚 xff1a VCC接5V电源正极 第3引脚
  • .Net Core 获取上下文HttpContext

    1 先定义一个类 using Microsoft AspNetCore Http namespace BCode Util public class MvcContext public static IHttpContextAccessor
  • XML有关知识

    可扩展标记语言 起初w3c为了严格语法 xff08 html在各个浏览器的恶性竞争下语法已经变得很松散了 xff09 推出了xml 功能 xff1a 存储数据 xff0c 1 配置文件使用 2 在网络中传输 转载于 https www cn
  • pixhawk代码移植到不同stm32芯片

    本文基于pixhawk1 0 1代码 xff0c 移植需要的知识很多 xff0c 一两个文章可说不清楚 xff0c 里面涉及到编译原理 xff0c 操作系统 xff0c stm32 xff0c 计算机组成原理等 xff0c 需要长期积累 x
  • 转 Pycharm及python安装详细教程

    转 xff1a http blog csdn net qq 29883591 article details 52664478 首先我们来安装Python 1 首先进入网站下载 xff1a 点击打开链接 xff08 或自己输入网址https
  • Python基础(6)——实现输入任意多个数,并计算其平均值

    学习了Python相关数据类型 xff0c 函数的知识后 xff0c 利用字符串的分割实现了输入任意多个数据 xff0c 并计算其平均值的小程序 思路是接收输入的字符串 xff0c 以空格为分隔符 xff0c 将分割的数据存入列表 xff0
  • 校园网破解

    今天刷酷安看到了校园网破解 xff0c 正好有时间研究下 首先了解一下校园网的机制 平时在家用的wifi均为外部网进来接路由器LAN端口 xff0c 在路由器里填入你的宽带账号密码 xff0c 开启DHCP即可 这里的校园进来插到了LAN口
  • 绝命毒师第一季/全集Breaking Bad迅雷下载

    本季Breaking Bad Season 1 2008 看点 xff1a 新墨西哥州的高中化学老师沃尔特 H 怀特 xff08 布莱恩 科兰斯顿 Bryan Cranston 饰 xff09 是拮据家庭的唯一经济来源 他大半生安分守己 x
  • Linux 释放socket资源,LwIP使用select,close socket资源释放不完全问题

    这篇文章本应该在4月就写好的 xff0c 但是博客评论系统一直没有搭建好 xff0c 走了很多弯路 xff0c 现在好了 xff0c delay这么久 xff0c 终于要要补过来了 自建博客 xff1a 金宝的博客 该文章完全原创 xff0
  • __FILE__,__LINE__,__DATE__,__TIME__ c++常用的预定义名字

    C 43 43 有四个常用的预定义名字 xff0c 分别为 FILE LINE DATE TIME FILE 记录文件的路径加名称 LINE 记录文件已经被编译的行数 DATE 记录文件的编译日期 TIME 记录文件的编译时间 可以当作变量
  • 串口拓展

    今天桌子下面找出一个破电路板看到一颗芯片GM8125 xff0c 这个芯片主要功能就是拓展串口 GM8125可以将一个全双工的标准串口扩展成5个标准串口 xff0c 并能通过外部引脚控制串口扩展模式 xff1a 单通道工作模式和多通道工作模
  • HttpUtils

    package com rs zero crc common http import com rs zero crc modulars common constants SysConstantConf import com xiaoleil
  • 【转】C语言中的位域、字节序、比特序、大小端

    1 比特序 位序 bit numbering bit endianness 我们知道一个字节有8位 xff0c 也就是8个比特位 从第0位到第7位共8位 比特序就是用来描述比特位在字节中的存放顺序的 通过阅读网页http en wikipe

随机推荐

  • 位定义方法定义寄存器

    寄存器 位域 定义的语法格式 xff1a Struct 位域结构名 类型说明符 位域名1 xff1a 位域长度 类型说明符 位域名2 xff1a 位域长度 类型说明符 位域名n xff1a 位于长度 从右到左申明的 位域的申明不能横跨两个字
  • Qt 模拟一个导航定位系统

    版权声明 xff1a 本文为博主原创文章 xff0c 遵循 CC 4 0 BY SA 版权协议 xff0c 转载请附上原文出处链接和本声明 本文链接 xff1a https www cnblogs com lihuidashen p 115
  • RESTful Api 身份认证中的安全性设计探讨

    REST 是一种软件架构风格 RESTful Api 是基于 HTTP 协议的 Api xff0c 是无状态传输 它的核心是将所有的 Api 都理解为一个网络资源 将所有的客户端和服务器的状态转移 xff08 动作 xff09 封装到 HT
  • 在STM32 MDK实现类似__attribute__((__packed__))效果

    attribute 是GNU C对标准C语法的扩展 xff0c 是GNU C的一大特色 xff0c 可以用于设置函数的属性 xff0c 变量的属性 xff0c 类型的属性 在STM32 MDK实现类似效果 xff1b 实验数据如下 xff1
  • 那些年搞不懂的多线程、同步异步及阻塞和非阻塞(一)---多线程简介

    1 进程和线程的概念 进程 xff1a 运行中的应用程序称为进程 xff0c 拥有系统资源 xff08 cpu 内存 xff09 线程 xff1a 进程中的一段代码 xff0c 一个进程中可以有多段代码 本身不拥有资源 xff08 共享所在
  • python爬虫登录保持及对http总结

    前言 这几天一直看python爬虫登录保持 实现接口太多 xff0c 太乱 xff0c 新手难免云山雾罩 各种get post xff0c 深入理解一下 xff0c 其实就是由于http的特性需要这些操作 http是一种无状态 不保存上次通
  • ROS CAN总线设备接入(一)Linux动态库的显式调用

    前提 xff1a xff08 1 xff09 xff0c 如果在libpcan安装正常的话 xff0c 那么可以用以下命令查找到libpcan so ls usr lib libpcan 查找到方可进行api载入 xff08 2 xff09
  • SQL Server 2012企业版和标准版的区别

    关于使用Microsoft SQL Server 数据库的公司一般会有疑问 xff0c 企业版数据库和标准版数据库的区别在哪 xff1f 如果采购企业版的价格和标准版的价格相差很大 xff0c 从多方资料查询发现 xff0c 我认为最主要的
  • 查询SQL SERVER 数据库版本号脚本语句

    数据库直接执行此语句即可 select 64 64 version 示例 xff1a Microsoft SQL Server 2014 12 0 2000 8 X64 Feb 20 2014 20 04 26 Copyright c Mi
  • SQL SERVER 还原误操作导致还原无法停止,处理办法

    昨天遇到运行库不知道单位哪个小伙子 xff0c 把数据库还原了 xff0c 导致单位业务全部瘫痪 xff0c 主数据库一直显示正在还原 xff0c 真的是不敢动 xff0c 经过多方寻找 xff0c 找到此脚本 数据库还原日志 xff0c
  • Docker安装及部署实例.Net Core

    1 什么是Docker Docker 是一个开源的应用容器引擎 xff0c 让开发者可以打包他们的应用以及依赖包到一个可移植的容器中 xff0c 然后发布到任何流行的 Linux 机器上 xff0c 也可以实现虚拟化 容器是完全使用沙箱机制
  • 将html格式的内容转换成纯文本格式

    最近做的一个东东 xff0c 想要去除掉保存的字符串内容的所有html格式 xff0c 也就是只取纯文本 xff0c 从网上查了些相关资料 xff0c 以及正则表达式的用法 xff0c 有一个方法向大家推荐 xff0c 基本去除了我想要去除
  • 待解决:PDF header signature not found

    转载于 https www cnblogs com ITGirl00 p 3531475 html
  • 从统计学看线性回归(2)——一元线性回归方程的显著性检验

    目 录 1 2 的估计 2 回归方程的显著性检验 t 检验 xff08 回归系数的检验 xff09 F 检验 xff08 回归方程的检验 xff09 相关系数的显著性检验 样本决定系数 三种检验的关系 一 2 的估计 因为假设检验以及构造与
  • TypeError: unsupported operand type(s) for +: 'float' and 'decimal.Decimal'

    TypeError unsupported operand type s for 43 39 float 39 and 39 decimal Decimal 39 浮点型和双精度类型 相加报错 from decimal import Dec
  • 7.模块化封装Storage实现缓存数据持久化

    1 模块化封装Storage实现缓存数据持久化 1 在src目录下新建目录model xff0c 在model目录下新建js文件取名storage js var storage 61 set key value 设置为本地缓存方法 loca
  • 8.使用scss,创建组件,scoped局部作用域

    1 使用scss scss是能让css从属关系看起来更加直观 在项目目录下运行安装命令 xff1a cnpm install node sass save dev cnpm install sass loader save dev 然后在项
  • 9.生命周期函数

    生命周期函数 xff0c 也叫生命周期钩子 xff0c 是指组件挂载以及组件销毁所触发的一系列的方法 在components目录下新建Life vue组件 xff0c 用于演示生命周期函数 lt template gt lt div gt
  • 经典教材--C语言程序设计(第五版)pdf

    下载地址 xff1a 网盘下载 下载地址 xff1a 网盘下载 转载于 https www cnblogs com long12365 p 9729993 html
  • c# 线程的等待(堵塞)

    这里我要强调一个概念 xff0c 多线程是多线程 xff0c 异步编程是异步编程 这两个是有区别的概念 xff1b 我可以说多线程天生就要异步的特点 xff1b 但你不能说多线程成就等同于我们的异步编程 xff1b 根不能说异步编程就是我们