C#非同步程式設計之淺談Task

weixin_33686714發表於2017-11-17

上一篇講到了.Net4.5新增的async和await關鍵字,其實async和await算是一組標記,真正實現非同步操作的是Task新開的任務執行緒。

什麼是Task

Task是.Net4.0新增用來處理非同步程式設計的,叫做基於“任務程式設計模型”,任務其實是架構線上程之上的,具體操作的時候還是由執行緒去執行的,任務的管控有點類似於執行緒池,程式中開10個Task,不一定對應的要開10個執行緒,他們並不是一一對應的關係。

  1. 建立Task 
    建立Task有兩種方式,一種是直接例項化,另一種是使用任務工廠生成。
Task<int> ts = new Task<int>(TaskTest, 100);

public static int TaskTest(object state)
        {
            int data = (int)state;
            int sum = 0;
            for (int i = 0; i < data; i++)
            {
                sum++;
            }
            return sum;
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

這裡第一個引數為方法委託,可以直接傳入要執行的方法名,值得注意的是這個方法的引數型別為object,若改為int,會編譯不過,具體可去檢視Task的建構函式的引數型別。 
當然也可以用Lamda表示式

Task<int> ts = new Task<int>((state) =>
            {
                int data = (int)state;
                int sum = 0;
                for (int i = 0; i < data; i++)
                {
                    sum++;
                }
                return sum;
            },10);
            ts.Start();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

例項化的Task物件,必須用Start方法啟動。 
第二種用任務工廠直接建立的無需用Start方法啟動執行,建立後就會執行

 Task<int> task = Task.Factory.StartNew<int>(
                (state) =>
                {
                    int data = (int)state;
                    int sum = 0;
                    for (int i = 0; i < data; i++)
                    {
                        sum++;
                    }
                    return sum;
                }, 10);

Task與Task的區別是,Task是沒有返回值的,而Task是有返回值的,且返回值型別為T,對於沒有返回值的Task,可用Wait方法等待其執行完成,有返回值得直接用task.Result即可,記住,在等待任務執行完的過程中,是會阻塞主執行緒的,這也就是async和await的的作用體現了。 
若有多個任務,比如任務1和任務2,且任務2要在任務1執行完畢後立刻啟動執行,下面就來介紹Task.ContinueWith

static void Main(string[] args)
        {
            Task<int> ts1 = new Task<int>(() => {
                return 100;
            });
            ts1.Start();
            var re = ts1.ContinueWith<int>((task) => {
                return task.Result + 200;
            });
            Console.WriteLine("執行結果:"+re.Result);
            Console.ReadLine();
        }

 

這裡寫圖片描述 
ContinueWith 需將ts1作為引數進行傳遞,即總可以把前面的一個Task用ContinueWith傳遞給下一個要執行的Task,下面是任務工廠的寫法

Task.Factory.StartNew<int>(() => { return 100; }).ContinueWith<int>(ts =>
            {
                return ts.Result + 200;

            }).ContinueWith(task => {
                Console.WriteLine("執行結果:" + task.Result);
            });
            Console.ReadLine();

相關文章