1. 程式人生 > 其它 >C#多執行緒之Await&Async學習筆記

C#多執行緒之Await&Async學習筆記

C# 5.0語法糖,依託Task存在,本身不會產生執行緒,達到了通過非同步方法實現同步效果的目的(解決非同步多執行緒執行順序難控制的問題)

1.定義

async可以隨便新增,可以不用新增await

await只能出在Task前面,但是方法必須宣告async,不能單獨出現

await/async之後,原本沒有返回值,可以返回Task

        原本返回T型別的,返回Task<T> 

        儘量不要返回void,因為不能再await了   

2.執行順序

namespace AwaitAsyncTest
{
    class Program
    {
        
static void Main(string[] args) { AwaitAsyncClassNew awaitTest = new AwaitAsyncClassNew(); awaitTest.Show(); Console.ReadKey(); } } class AwaitAsyncClassNew { public void Show() { Console.WriteLine($"This is MainThread Start{Thread.CurrentThread.ManagedThreadId}
"); this.NoReturnTask(); Console.WriteLine($"This is MainThread End {Thread.CurrentThread.ManagedThreadId}"); } public async Task NoReturnTask() { Console.WriteLine($"This is NoReturnTask Start{Thread.CurrentThread.ManagedThreadId}"); Task task
= Task.Run(() => { Console.WriteLine($"NoReturnTask Start{Thread.CurrentThread.ManagedThreadId}"); Thread.Sleep(1000); Console.WriteLine($"NoReturnTask End{Thread.CurrentThread.ManagedThreadId}"); });//呼叫執行緒發起,啟動新執行緒執行內部動作 await task;//呼叫執行緒回去忙自己的事 Console.WriteLine($"This is NoReturnTask End{Thread.CurrentThread.ManagedThreadId}");//由子執行緒完成(如果沒有await,應該由呼叫執行緒執行) }   }

執行結果:

This is MainThread Start1
This is NoReturnTask Start1
This is MainThread End 1
NoReturnTask Start3
NoReturnTask End3
This is NoReturnTask End3 --本來屬於主執行緒的卻被子執行緒執行了

相當於await的後續程式碼包裝成了一個回撥,執行次此回撥的執行緒有多種可能性

將await開始的程式碼換成

        public async Task NoReturnTask()
        {
            Console.WriteLine($"This is NoReturnTask Start{Thread.CurrentThread.ManagedThreadId}");
            Task task = Task.Run(() =>
            {
                Console.WriteLine($"NoReturnTask Start{Thread.CurrentThread.ManagedThreadId}");
                Thread.Sleep(1000);
                Console.WriteLine($"NoReturnTask End{Thread.CurrentThread.ManagedThreadId}");
            });
            //await task;
            //Console.WriteLine($"This is NoReturnTask End{Thread.CurrentThread.ManagedThreadId}");
            task.ContinueWith(t => 
                Console.WriteLine($"This is NoReturnTask End{Thread.CurrentThread.ManagedThreadId}"));
        }

結果為

This is MainThread Start1
This is NoReturnTask Start1
This is MainThread End 1
NoReturnTask Start3
NoReturnTask End3
This is NoReturnTask End4

如果再更多層的await,執行順序依次向後(更像是順序執行了),相當於用同步的形式去寫非同步

public async Task NoReturnTask()
        {
            Console.WriteLine($"This is NoReturnTask Start{Thread.CurrentThread.ManagedThreadId}");
            Task task = Task.Run(() =>
            {
                Console.WriteLine($"NoReturnTask Start{Thread.CurrentThread.ManagedThreadId}");
                Thread.Sleep(1000);
                Console.WriteLine($"NoReturnTask End{Thread.CurrentThread.ManagedThreadId}");
            });
            await task;
            Console.WriteLine($"This is NoReturnTask End{Thread.CurrentThread.ManagedThreadId}");
            //task.ContinueWith(t => 
            //    Console.WriteLine($"This is NoReturnTask End{Thread.CurrentThread.ManagedThreadId}"));
            await Task.Run(() =>
            {
                Console.WriteLine($"NoReturnTask2 Start{Thread.CurrentThread.ManagedThreadId}");
                Thread.Sleep(1000);
                Console.WriteLine($"NoReturnTask2 End{Thread.CurrentThread.ManagedThreadId}");
            });
            Console.WriteLine($"This is NoReturnTask2 End{Thread.CurrentThread.ManagedThreadId}");

        }

結果為

This is MainThread Start1
This is NoReturnTask Start1
NoReturnTask Start3
This is MainThread End 1 --主執行緒結束
NoReturnTask End3
This is NoReturnTask End3 --執行完task1
NoReturnTask2 Start4 ---執行Task2
NoReturnTask2 End4
This is NoReturnTask2 End4

3.執行緒ID問題

4.返回值問題