2017-01-01-線程開啟方式-1-異步委托(同步)

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

namespace _2016_12_29_羅斯_線程
{
    class Program
    {
        //一般來說,程序執行都是從上而下,打印順序應該是先打印Tes1這個上面的方法再打印下面的Main方法
        //然而啟用了線程后,打印出的文字順序則變成了Main的文字出現在第一行,Test1在第二行
        //事實上,啟用了線程后,cpu從兩者中隨機調用,并不存在誰先誰后一說

        //1.聲明一個普通無參數無返回值的方法Test1
        static void Test1()
        {
            Console.WriteLine("無返回值無參數普通方法程序執行啦!");
        }

        //4.無返回值有傳遞參數的方法
        static void Test2(int i,string str)
        {
            Console.WriteLine("無返回值有參數的"+i+"XX"+"的普通方法程序開始啦!");
        }

        //7.有返回值有參數的方法
        static int Test3(int t, string str)//12.為了模擬耗時操作,在return前輸入Thread.Sleep(100);
        {
            Console.WriteLine("有返回值,有參數的" + t +"XX"+ "的普通方法程序開始啦!");
            Thread.Sleep(100);
            //13.Thread是在using System.Threading;里的,所以命名空間沒有的話需要補寫using System.Threading;
            //Thread.Sleep讓當前線程休眠(暫停線程的執行),單位是毫秒:ms,100ms相當于0.1秒

            return 100;
        }
        


        static void Main(string[] args)//在main線程中執行
        //一個線程里面語句的執行是從上到下的!
        {
            //2.通過聲明一個委托去開啟一個線程
            Action a = Test1;

            //5.相應的委托類型及委托變量之間要添加泛型尖括號,里面填方法對應的類型
            Action<int,string> b = Test2;

            //3.用委托的變量名.BeginInvoke方法,開啟一個新的線程,去執行變量a所引用的方法Test1 
            a.BeginInvoke(null, null);//括號里的2個參數暫時用null空值代替


            //6.傳參數
            b.BeginInvoke(100,"羅斯",null, null);

            //可以認為線程是同時執行的,也就是異步執行或者并行
            Console.WriteLine("Main開啟線程的方法啟動啦!快看我跟普通方法是不是一起出現~!");

            //8.由于有返回值類型,所以只能用Func委托
            Func<int, string, int> c = Test3;
            c.BeginInvoke(100, "XX", null, null);

            //10.c.BeginInvoke(100, "XX", null, null)有個返回值是IAsyncResult類型的
            IAsyncResult ar = c.BeginInvoke(100, "XX", null, null);
            //IAsyncResult 可以取得當前線程的狀態

            //假設此時Test3運行時間較長,這里則不會立即獲得返回值。
            //一般我們會為比較耗時間的操作,開啟單獨的線程去執行:比如下載操作(Test3),下載完之后需要獲得文件路徑(return)什么的
            
            //想要獲取線程的返回值,首先要判斷這個線程是否執行結束,結束即可得。
            //9.想要在Main方法里獲取返回值,則首先要建立一個死循環做一個判斷。
            while (ar.IsCompleted == false)//11.變量ar有個“是否完畢”的屬性IsCompleted,如果當前線程沒有執行完畢(false)
            {
                //12.如果沒完畢,則輸出字符串
                Console.WriteLine("程序仍在執行中......");
                
                //16.也可以讓此線程暫停10ms,可以減少字符串的輸出,也就是每10ms檢測一次,控制子線程的檢測有沒有結束的頻率
                Thread.Sleep(10);

            }
            //14.當跳出while死循環,程序執行完畢,我們就可以取得Test3的執行結果
            //而Test3的結果是通過委托c(Func c)去調用的,所以可以通過c去取得結果
            //且c的線程狀態是用過IAsyncResult ar去取得的
            //所以用c.EndInvoke方法,且把線程狀態的變量結果ar傳遞過去
            //再用int res去接收這個返回值(因為Test3里return的是100,所以用int),即取得異步線程的返回值
            int res = c.EndInvoke(ar);

            //15.輸出返回值
            Console.WriteLine(res);

            Console.ReadKey();
        }
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容