C#同步調(diào)用、異步調(diào)用、異步回調(diào)、Task類、async/wait

  class AsyncClass
    {
        //聲明委托
        private delegate int AddHandler(int a, int b);

        //代理方法
        public int Add(int a, int b)
        {
            Thread.Sleep(1000 * 3);
            Console.WriteLine("ThreadID--" + Thread.CurrentThread.ManagedThreadId);
            return a + b;
        }

        //同步調(diào)用,阻塞當(dāng)前線程,順序執(zhí)行
        public void Tongbu()
        {
            AddHandler handler = new AddHandler(Add);
            int result = handler.Invoke(8, 5);

            Console.WriteLine(result);

            Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffffffff"));

            Console.WriteLine(handler(4, 5));

            Console.WriteLine("Tongbu Done!");
        }

        //異步調(diào)用
        public void Yibu()
        {
            AddHandler handler = new AddHandler(Add);

            for (int i = 1; i <= 5; i++)
            {
                //相當(dāng)于另開了5個(gè)線程去執(zhí)行Add方法
                IAsyncResult result = handler.BeginInvoke(i, i, new AsyncCallback(CallBack), "AsycState:OKaaa");
            }

            Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffffff"));

            //沒有回調(diào)時(shí)也必須使用EndInvoke方法。BeginInvoke和EndInvoke必須同時(shí)出現(xiàn),否則可能發(fā)生內(nèi)存泄漏
            //Console.WriteLine(handler.EndInvoke(result));

            Console.WriteLine("Yibu Done!");

            Console.ReadKey();
        }

        //異步回調(diào)方法
        public void CallBack(IAsyncResult result)
        {
            //AsyncResult 是IAsyncResult接口的一個(gè)實(shí)現(xiàn)類,空間:System.Runtime.Remoting.Messaging
            //AsyncDelegate 屬性可以強(qiáng)制轉(zhuǎn)換為用戶定義的委托的實(shí)際類。
            AddHandler handler = (AddHandler)((AsyncResult)result).AsyncDelegate;

            Console.WriteLine(handler.EndInvoke(result));
            Console.WriteLine(result.AsyncState);
            Console.WriteLine("CallBack Done!");
        }


        //線程池
        AutoResetEvent are = new AutoResetEvent(false); //信號(hào)燈
        int num = 10;
        public void ThreadPoolTest()
        {
            ThreadPool.SetMinThreads(1, 1);
            ThreadPool.SetMaxThreads(5, 5);

            for (int i = num; i >= 0; i--)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(CallBack2),i.ToString());
            }

            Console.WriteLine("主線程執(zhí)行!");

            are.WaitOne();//阻塞當(dāng)前線程,直到are執(zhí)行了Set方法
            Console.WriteLine("主線程結(jié)束!");
            Console.ReadKey();
        }

        //線程池回調(diào)方法
        public void CallBack2(object obj)
        {
            num--;
            Console.WriteLine(string.Format("{0}:第{1}個(gè)線程", DateTime.Now.ToString(), obj.ToString()));
            Thread.Sleep(1000);
            if (num == -1)
                are.Set();
        }


        //Task創(chuàng)建和運(yùn)行  無(wú)返回值
        public void TaskTest()
        {
            //方式一
            Task task1 = new Task(() =>
            {
                Thread.Sleep(200);
                Console.WriteLine("void當(dāng)前線程ID = {0}", Thread.CurrentThread.ManagedThreadId);
            });
            task1.Start();

            //方式二
            Task task2 = Task.Factory.StartNew(() =>
            {
                Thread.Sleep(200);
                Console.WriteLine("void當(dāng)前線程ID = {0}", Thread.CurrentThread.ManagedThreadId);
            });

            //方式三
            Task task3 = Task.Run(() =>
            {
                Thread.Sleep(200);
                Console.WriteLine("void當(dāng)前線程ID = {0}", Thread.CurrentThread.ManagedThreadId);
            });

            Console.WriteLine("主線程 void");
            Console.WriteLine("主線程 void Done!");
        }

        //Task創(chuàng)建和運(yùn)行  有返回值
        public void TaskReturnTest()
        {
            //方式一
            Task<string> task1 = new Task<string>(() =>
            {
                Thread.Sleep(200);
                return string.Format("當(dāng)前線程ID = {0}", Thread.CurrentThread.ManagedThreadId);
            });
            //task1.Start();

            //方式二
            Task<string> task2 = Task.Factory.StartNew<string>(() =>
            {
                Thread.Sleep(200);
                return string.Format("當(dāng)前線程ID = {0}", Thread.CurrentThread.ManagedThreadId);
            });

            //方式三
            Task<string> task3 = Task.Run<string>(() =>
            {
                Thread.Sleep(200);
                return string.Format("當(dāng)前線程ID = {0}", Thread.CurrentThread.ManagedThreadId);
            });

            task1.RunSynchronously(); //阻塞主線程,直到task1線程執(zhí)行完

            task2.Wait(); //等待task2執(zhí)行完

            Task.WaitAll(new Task[] { task1, task2, task3 }); //等待所有task執(zhí)行完

            Task.WaitAny(new Task[] { task1, task2, task3 }); //等待任何一個(gè)task執(zhí)行完

            Console.WriteLine("主線程 Return");
            Console.WriteLine(task1.Result);
            Console.WriteLine(task2.Result);
            Console.WriteLine(task3.Result);

            //至少一個(gè)task執(zhí)行完,去執(zhí)行后續(xù)操作
            Task.WhenAny(new Task[] { task1, task2, task3 }).ContinueWith((t) =>
            {
                Console.WriteLine("至少有一個(gè)task執(zhí)行完了。。。。。" );
            });

            //所有的task執(zhí)行完,去執(zhí)行后續(xù)操作
            Task.WhenAll(new Task[] { task1, task2, task3 }).ContinueWith((t) =>
            {
                Console.WriteLine("所有的task都執(zhí)行完了。。。。。");
            });

            //等同于Task.WhenAny
            Task.Factory.ContinueWhenAny(new Task[] { task1, task2, task3 }, (t) =>
            {
                Console.WriteLine("至少有一個(gè)task執(zhí)行完了。。。。。");
            });

            //等同于Task.WhenAll
            Task.Factory.ContinueWhenAll(new Task[] { task1, task2, task3 }, (t) =>
            {
                Console.WriteLine("所有的task都執(zhí)行完了。。。。。");
            });

            Console.WriteLine("主線程 Return Done!");

            Console.ReadKey();
        }

        //Task取消任務(wù),并設(shè)置取消任務(wù)后觸發(fā)的事件
        public void TaskCancelTest()
        {
            CancellationTokenSource source = new CancellationTokenSource();

            //注冊(cè)任務(wù)取消觸發(fā)的事件
            source.Token.Register(() =>
            {
                Console.WriteLine("任務(wù)已取消");
            });
            int index = 0;
            Task task = new Task(() =>
            {
                while(!source.IsCancellationRequested)
                {
                    Thread.Sleep(500);
                    Console.WriteLine(++index);
                }
            });
            task.Start();

            //10000毫秒后停止運(yùn)行task
            source.CancelAfter(10000);

            Console.ReadKey();
        }


        //異步方法 Async、await
        public static async Task<string> GetFileContentAsync(string fileName)
        {
            FileStream fs = new FileStream(fileName, FileMode.Open);
            var bytes = new byte[fs.Length];
            Console.WriteLine("開始讀取文件");
            int len = await fs.ReadAsync(bytes, 0, bytes.Length);
            string result = Encoding.Default.GetString(bytes);
            return result;
        }

        public static async Task GetFileContentAsync2(string fileName)
        {
            FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
            var bytes = new byte[fs.Length];
            Console.WriteLine("開始讀取文件");
            int len = await fs.ReadAsync(bytes, 0, bytes.Length);
            string result = Encoding.UTF8.GetString(bytes);
            return;
        }

        public static async void GetFileContentAsync3(string fileName)
        {
            FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
            var bytes = new byte[fs.Length];
            Console.WriteLine("開始讀取文件");
            int len = await fs.ReadAsync(bytes, 0, bytes.Length);
            string result = Encoding.UTF8.GetString(bytes);
        }
    }

一次運(yùn)行結(jié)果:

image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容