天天看點

多核時代 .NET Framework 4 中的并行程式設計2---任務并行庫之Task (上)

.     任務并行庫

任務并行庫 (Task Parallel Library) 是 .NET Framework 4 版的 System.Threading 和 System.Threading.Tasks 命名空間中的一組公共類型和 API。 TPL 的目的在于簡化向應用程式中添加并行性和并發性的過程,進而提高開發人員的工作效率。TPL 會動态地按比例調節并發程度,以便最有效地使用所有可用的處理器。 此外,TPL 還處理工作分區、ThreadPool 上的線程排程、取消支援、狀态管理以及其他低級别的細節操作。 通過使用 TPL,您可以在将精力集中于程式要完成的工作,同時最大程度地提高代碼的性能。

從 .NET Framework 4 開始,TPL 是編寫多線程代碼和并行代碼的首選方法。 但是,并不是所有代碼都适合并行化;例如,如果某個循環在每次疊代時隻執行少量工作,或它在很多次疊代時都不運作,那麼并行化的開銷可能導緻代碼運作更慢。 此外,像任何多線程代碼一樣,并行化會增加程式執行的複雜性。 盡管 TPL 簡化了多線程方案,但我們建議您對線程處理概念(例如,鎖、死鎖和争用條件)進行基本的了解,以便能夠有效地使用 TPL。

下面,将介紹并行庫中一個重要的類:Task.它表示一個異步操作.

2.     Task基本使用:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

namespace AppParallel

{

    class Program

    {

        static void Main(string[] args)

        {

            Task task1 = new Task(new Action(SayHello));

            Task task2 = new Task(delegate

                {

                    SayHello();

                });

            Task task3 = new Task(() => SayHello());

            Task task4 = new Task(() =>

            {

                SayHello();

            });

            task1.Start();

            task2.Start();

            task3.Start();

            task4.Start();

            Console.WriteLine("Main 執行完畢!");

            Console.ReadLine();

        }

        static void SayHello()

            Console.WriteLine("Hello C# Parallel!");

    }

}

上面的例子中,我們首先需要引用System.Threading.Tasks名空間,這個命名空間是.Net4中新增加的.同時,我們可以編寫并行代碼很簡單,需要申明一個Task的執行個體,然後調用他的Start()方法即可.

Task類的提供以下構造函數:

(1)           Task(Action) 

使用指定的操作初始化新的 Task。  

(2)           Task(Action, CancellationToken) 

用指定的操作和 CancellationToken 初始化新的 Task。 

(3)           Task(Action, TaskCreationOptions) 

使用指定的操作和建立選項初始化新的 Task。 

(4)           Task(Action<Object>, Object) 

使用指定的操作和狀态初始化新的 Task。 

(5)           Task(Action, CancellationToken, TaskCreationOptions) 

使用指定的操作和建立選項初始化新的 Task。

(6)           Task(Action<Object>, Object, CancellationToken) 

使用指定的操作、狀态和選項初始化新的 Task。 

(7)           Task(Action<Object>, Object, TaskCreationOptions) 

(8)           Task(Action<Object>, Object, CancellationToken, TaskCreationOptions) 

使用指定的操作、狀态和選項初始化新的 Task

其中,TaskCreationOptions用來指定可控制任務的建立和執行的可選行為的标志。可用的枚舉如下:

Ø None 指定應使用預設行為。 

Ø PreferFairness 提示 TaskScheduler 以一種盡可能公平的方式安排任務,這意味着較早安排的任務将更可能較早運作,而較晚安排運作的任務将更可能較晚運作。 

Ø LongRunning 指定某個任務将是運作時間長、粗粒度的操作。 它會向TaskScheduler 提示,過度訂閱可能是合理的。 

Ø AttachedToParent 指定将任務附加到任務層次結構中的某個父級。 

3.     傳入參數

編寫代碼傳遞參數是常見的,那麼在Task中如何将參數傳入在執行的代碼中呢?此時,我們需要使用Task的Task(Action<Object>, Object)這個構造函數.例子如下:

using System.Threading;

            Task task1 = new Task(new Action<object>(DisplayTime),DateTime.Now);

            Task task2 = new Task(delegate(object obj)

                    DisplayTime(obj);

                }, DateTime.Now);

            Task task3 = new Task((obj) => DisplayTime(obj),DateTime.Now);

            Task task4 = new Task((obj) =>

                DisplayTime(obj);

            }, DateTime.Now);

            Console.WriteLine("執行完畢!");

        static void DisplayTime(object dt)

            Console.WriteLine("現在時間是:" + ((DateTime)dt).ToLocalTime());

4.     傳回結果

我們可以通過Task<T>執行個體的Result來擷取代碼執行的傳回結果,其中T表示傳回結果的類型,例子:

 static void Main(string[] args)

 {

           Task<bool> t = new Task<bool>(Contains, "xzdf2a");

            t.Start();

            Console.WriteLine("Main執行完畢!");

            Console.WriteLine("Task傳回的結果:" + t.Result.ToString());

 }

static bool Contains(object obj)

            string s = obj as string;

            if (s != null)

                return s.Contains('a');

            }

            return false;

    本文轉自風車車  部落格園部落格,原文連結:http://www.cnblogs.com/xray2005/archive/2011/08/21/2147625.html,如需轉載請自行聯系原作者