国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

C# 多線程編程入門

2019-11-08 01:44:54
字體:
來源:轉載
供稿:網友

收集部分C#多線程編程入門級知識

C#通過多線程支持并行執行的代碼。一個線程是一個獨立執行的路徑,可以同時與其他線程一起運行。一個C#客戶端程序(Console,WPF,Winows Forms)開始于一個單獨的線程,該線程由CLR和操作系統自動地創建,我們稱它為主線程,而且可以通過創建附加的線程來實現多線程。

一、使用線程的理由

1、可以使用線程將代碼同其他代碼隔離,提高應用程序的可靠性。

2、可以使用線程來簡化編碼。

3、可以使用線程來實現并發執行。

二、基本知識

1、進程與線程:進程作為操作系統執行程序的基本單位,擁有應用程序的資源,進程包含線程,進程的資源被線程共享,線程不擁有資源。

2、前臺線程和后臺線程:通過Thread類新建線程默認為前臺線程。當所有前臺線程關閉時,所有的后臺線程也會被直接終止,不會拋出異常。

3、掛起(Suspend)和喚醒(Resume):由于線程的執行順序和程序的執行情況不可預知,所以使用掛起和喚醒容易發生死鎖的情況,在實際應用中應該盡量少用。

4、阻塞線程:Join,阻塞調用線程,直到該線程終止。

5、終止線程:Abort:拋出 ThreadAbortException 異常讓線程終止,終止后的線程不可喚醒。Interrupt:拋出 ThreadInterruptException 異常讓線程終止,通過捕獲異常可以繼續執行。

6、線程優先級:AboveNormal BelowNormal Highest Lowest Normal,默認為Normal。

三、線程的使用

線程函數通過委托傳遞,可以不帶參數,也可以帶參數(只能有一個參數),可以用一個類或結構體封裝參數。

需要:

using System.Threading;

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Threading;namespace 線程的使用{    class PRogram    {        static void Main(string[] args)        {            Thread t1 = new Thread(new ThreadStart(TestMethod));//創建一個新線程            Thread t2 = new Thread(new ParameterizedThreadStart(TestMethod));            Thread t3 = new Thread(Count);            Thread t4 = new Thread(Count2);            t3.Start();//開始該線程            t4.Start();//由于循環次數多,可以看到a和數字同時交叉輸出            t1.IsBackground = true;            t2.IsBackground = true;            t1.Start();            t2.Start("hello");            Console.ReadKey();        }        public static void TestMethod()        {            Console.WriteLine("不帶參數的線程函數");        }        public static void TestMethod(object data)        {            string datastr = data as string;            Console.WriteLine("帶參數的線程函數,參數為:{0}", datastr);        }        public static void Count()        {            for (int i = 0; i < 10000; i++)            {                if (0==(i+1)%25)                {                    Console.Write("/r/n");                }                Console.Write(i);                Console.Write(" ");            }            Console.Write("/r/n");        }        public static void Count2()        {            for (int i = 0; i < 10000; i++)            {                if (0 == (i + 1) % 25)                {                    Console.Write("/r/n");                }                Console.Write("a");                Console.Write(" ");            }            Console.Write("/r/n");        }    }}一旦開始,一個線程的IsAlive屬性返回true,直到這個線程結束。當傳遞給線程的構造函數的委托完成執行時,這個線程結束。一旦結束,這個線程不能重啟。

四、線程池

由于線程的創建和銷毀需要耗費一定的開銷,過多的使用線程會造成內存資源的浪費,出于對性能的考慮,于是引入了線程池的概念。線程池維護一個請求隊列,線程池的代碼從隊列提取任務,然后委派給線程池的一個線程執行,線程執行完不會被立即銷毀,這樣既可以在后臺執行任務,又可以減少線程創建和銷毀所帶來的開銷。

線程池線程默認為后臺線程(IsBackground)。

namespace Test{    class Program    {        static void Main(string[] args)        {            //將工作項加入到線程池隊列中,這里可以傳遞一個線程參數            ThreadPool.QueueUserWorkItem(TestMethod, "Hello");            Console.ReadKey();        }        public static void TestMethod(object data)        {            string datastr = data as string;            Console.WriteLine(datastr);        }    }}

五、Task類

使用ThreadPool的QueueUserWorkItem()方法發起一次異步的線程執行很簡單,但是該方法最大的問題是沒有一個內建的機制讓你知道操作什么時候完成,有沒有一個內建的機制在操作完成后獲得一個返回值。為此,可以使用System.Threading.Tasks中的Task類。

構造一個Task<TResult>對象,并為泛型TResult參數傳遞一個操作的返回類型。

namespace Test{    class Program    {        static void Main(string[] args)        {            Task<Int32> t = new Task<Int32>(n => Sum((Int32)n), 1000);            t.Start();            t.Wait();            Console.WriteLine(t.Result);            Console.ReadKey();        }        private static Int32 Sum(Int32 n)        {            Int32 sum = 0;            for (; n > 0; --n)                checked{ sum += n;} //結果太大,拋出異常            return sum;        }    }}

一個任務完成時,自動啟動一個新任務。一個任務完成后,它可以啟動另一個任務,下面重寫了前面的代碼,不阻塞任何線程。

namespace Test{    class Program    {        static void Main(string[] args)        {            Task<Int32> t = new Task<Int32>(n => Sum((Int32)n), 1000);            t.Start();            //t.Wait();            Task cwt = t.ContinueWith(task => Console.WriteLine("The result is {0}",t.Result));            Console.ReadKey();        }        private static Int32 Sum(Int32 n)        {            Int32 sum = 0;            for (; n > 0; --n)                checked{ sum += n;} //結果溢出,拋出異常            return sum;        }    }}

六、委托異步執行

委托的異步調用:BeginInvoke() 和 EndInvoke()

namespace Test{    public delegate string MyDelegate(object data);    class Program    {        static void Main(string[] args)        {            MyDelegate mydelegate = new MyDelegate(TestMethod);            IAsyncResult result = mydelegate.BeginInvoke("Thread Param", TestCallback, "Callback Param");            //異步執行完成            string resultstr = mydelegate.EndInvoke(result);        }        //線程函數        public static string TestMethod(object data)        {            string datastr = data as string;            return datastr;        }        //異步回調函數        public static void TestCallback(IAsyncResult data)        {            Console.WriteLine(data.AsyncState);        }    }}

七、線程同步

  1)原子操作(Interlocked):所有方法都是執行一次原子讀取或一次寫入操作。

  2)lock()語句:避免鎖定public類型,否則實例將超出代碼控制的范圍,定義private對象來鎖定。

  3)Monitor實現線程同步

    通過Monitor.Enter() 和 Monitor.Exit()實現排它鎖的獲取和釋放,獲取之后獨占資源,不允許其他線程訪問。

    還有一個TryEnter方法,請求不到資源時不會阻塞等待,可以設置超時時間,獲取不到直接返回false。

  4)ReaderWriterLock

    當對資源操作讀多寫少的時候,為了提高資源的利用率,讓讀操作鎖為共享鎖,多個線程可以并發讀取資源,而寫操作為獨占鎖,只允許一個線程操作。

  5)事件(Event)類實現同步

    事件類有兩種狀態,終止狀態和非終止狀態,終止狀態時調用WaitOne可以請求成功,通過Set將時間狀態設置為終止狀態。

    1)AutoResetEvent(自動重置事件)

    2)ManualResetEvent(手動重置事件)

  6)信號量(Semaphore)

      信號量是由內核對象維護的int變量,為0時,線程阻塞,大于0時解除阻塞,當一個信號量上的等待線程解除阻塞后,信號量計數+1。

      線程通過WaitOne將信號量減1,通過Release將信號量加1,使用很簡單。

  7)互斥體(Mutex)

      獨占資源,用法與Semaphore相似。

   8)跨進程間的同步

      通過設置同步對象的名稱就可以實現系統級的同步,不同應用程序通過同步對象的名稱識別不同同步對象。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 武乡县| 本溪| 镇平县| 波密县| 凌源市| 法库县| 盐源县| 嘉义县| 喜德县| 沈丘县| 从化市| 南宁市| 乐清市| 白河县| 历史| 交城县| 宜兰县| 绵阳市| 东平县| 广德县| 延庆县| 巴楚县| 巍山| 鹿邑县| 贵定县| 吕梁市| 垫江县| 台东县| 深泽县| 承德市| 永定县| 宝山区| 大化| 会宁县| 黄龙县| 靖州| 赞皇县| 定襄县| 天镇县| 顺义区| 遂宁市|