• c# 线程的等待(堵塞) 2019-07-20 19:01:31
    多线程多线程, 异步编程是异步编程 这两个是有区别的概念; 我可以说多线程天生就要异步的特点;但你不能说多线程成就等同于我们的异步编程; 根不能说异步编程就是我们的多线程。这里不要搞混淆了; 再net...

     

    这里我要强调一个概念,

     多线程是多线程,

    异步编程是异步编程

    这两个是有区别的概念;

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

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

    再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

    展开全文
  • C#线程中的等待与阻塞 2013-06-12 15:34:53
    C#多线程运行的过程中,会遇到先运行哪个线程和后运行哪个线程的问题,这需要用到ManualResetEvent类。 ManualResetEvent类允许不同线程通过互发信号和等待彼此的信号来达到线程同步的目的。 它有三个重要的...
  • C#线程阻塞、中断与终止 2010-05-20 09:39:00
    阻塞、中断:在一个线程中调用Thread.Sleep方法会导致该线程立即被阻塞阻塞的时间长度等于传递给Thread.Sleep方法的数值(单位为毫秒)。如果调用Thread.Sleep方法时传入的参数为Timeout.Infinit,那么当前线程将...
  • C#常用多线程方法 2016-12-30 23:55:09
    1. Thread类 C#多线程编程中Thread类需要包含名称空间System.Threading。 class Program { static void Main(string[] args) { Thread thread01 = new Thread(ThreadTask01); thread0
  • 入门线程小例子C#支持通过多线程并行地执行代码,一个线程有它独立的执行路径,能够与其它的线程同时地运行。一个C#程序开始于一个单线程,这个单线程是被CLR和操作系统(也称为“主线程”)自动创建的,并具有...
  • C#异步调用(Asynchronou Delegate) C#异步调用获取结果方法:主要有三种,也可以说是四种(官方说四种,电子书说三种),官方在MSDN上已经有详细的说明: 链接 需要了解到获取异步执行的返回值,意味着你需要...
  • C# 多线程防止卡死 2016-08-19 16:29:59
    软件界面的响应特性是判断一款软件的非常重要的方面。一般来说,不管你软件功能做得有多么奇妙,如果软件有一点点死机的感觉都会让用户感到很讨厌,甚至怀疑你软件里是否藏有更大的...不过,使用多线程比使用单一线程
  • 多线程的意义在于一个应用程序中,有多个执行部分可以同时执行:一个线程可以在后台读取数据,而另一个线程可以在前台展现已读取的数据。 C#支持通过多线程并行地执行代码,一个线程有它独立的执行路径,能够与其它...
  • 线程嵌套指的是:线程A的执行代码启动了线程B,线程B的执行代码又启动了线程C。 我原本以为线程A被Abort后,线程B会自动被Abort,但是我大错特错了。 在这种场景下,线程的管理就非常重要了。 线程A被Abort后线程B...
  • C#多线程编程:线程同步 2019-06-05 18:35:58
    正如前面所看到的一样,多个线程同时使用共享对象会造成很多问题。同步这些线程使得对共享对象的操作...导致这问题的原因是多线程的执行并没有正确同步。当一个线程执行递增和递减操作时,其他线程需要依次等待。这种...
  • C#多线程之线程池篇1 2018-05-28 17:22:49
    C#多线程之线程池篇中,我们将学习多线程访问共享资源的一些通用的技术,我们将学习到以下知识点:在线程池中调用委托在线程池中执行异步操作线程池和并行度实现取消选项使用等待句柄和超时使用计时器使用...
  • c#-线程-非阻塞线程实践 2019-10-16 11:18:16
    需求: 1.先创建一个列表并放置数据若干(这里:0~9)。...阻塞线程实现 1.运行效果 2.代码 using System; using System.Collections.Generic; using System.Threading; namespace 非阻塞线程模拟 { ...
  • C#多线程基础概念 2018-12-26 10:06:15
    C#多线程1 :信号量Semaphore 通过使用一个计数器对共享资源进行访问控制,Semaphore构造器需要提供初始化的计数器(信号量)大小以及最大的计数器大小 访问共享资源时,程序首先申请一个向Semaphore申请一个许可...
  • C#多线程编程 2019-06-20 16:02:12
    一、基本概念 进程:当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存...多线程多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,...
  • 本文是一篇读书笔记,由《C#多线程编程实战》一书中的内容整理而来,主要梳理了.NET中多线程编程相关的知识脉络,从Thread、ThreadPool、Task、async/await、并发集合、Parallel、PLINQ到Rx及异步I/O等内容,均有所...
  • C#多线程——线程同步 2018-08-25 13:11:53
    线程同时使用共享对象会造成很问题,同步这些线程使得对共享对象的操作能够以正确的顺序执行是非常重要的。 二、实现线程同步的方法: • 使用Mutex类 • 使用SemaphoreSlim类 • 使用AutoResetEvent类 • ...
  • C#多线程编程实战(一):线程基础1.1 简介多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体...
  • C#多线程实例汇总 2020-03-15 10:41:58
    我汇总了一下关于C#多线程的使用方法,包括一些简单的锁和线程池的常用方法,虽然古老了一些,但是在一些老的项目中还是能经常用到的,多线程和异步有点儿小区别,分两篇文章来汇总,下一篇我再总结一下关于C#异步的...
  • 本文主要描述在C#中线程同步的方法。线程的基本概念网上资料也很多就不再赘述了。直接接入 主题,在多线程开发的应用中,线程同步是不可避免的。在.Net框架中,实现线程同步主要通过以下的几种方式来实现,在MSDN的...
  • C#多线程和线程池 2019-05-08 08:43:13
    Windows系统是一个多线程的操作系统。一个程序至少有一个进程,一个进程至少有一个线程。进程是线程的容器,一个C#客户端程序开始于一个单独的线程,CLR(公共语言运行库)为该进程创建了一个线程,该线程称为主线程。...
1 2 3 4 5 ... 20
收藏数 25,383
精华内容 10,153