c# 線程的等待(堵塞)

來源:互聯網
上載者:User

標籤:name   syn   問題   pre   auto   obj   result   public   混淆   

 

這裡我要強調一個概念,

 多線程是多線程,

非同步編程是非同步編程

這兩個是有區別的概念;

我可以說多線程天生就要非同步特點;但你不能說多線程成就等同於我們的非同步編程;

根不能說非同步編程就是我們的多線程。這裡不要搞混淆了;

再net中的進化如下:

多線程:Thread =>ThreadPool=> Task

非同步編程:BenginInvokeXXX EndInvokeXXX IAsyncResult=> async await (這裡面配合著Task的使用)。

好接下來,再來總結我們的線程(任務)的等待。

總結:

方法一: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 之後,通知多個線程的執行個體,或則理解成為廣播是似的傳遞訊息;

或則:多個線程在等待某一個線程的訊號;

 

c# 線程的等待(堵塞)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.