当前位置:编程学习 > asp >>

.NET 4中的多线程编程之一:使用Task

 

.NET 4为了简化多线程编程,提供了System.Threading.Tasks命名空间中的类来帮助开发者进行多线程编程,其中,Task类用来表示一个线程。最简单的Task类接受一个Action委托作为要执行的方法,调用Start方法开始在另一个线程中运行。例如:

using System;

using System.Threading.Tasks;

namespace TaskParallel

{

    class Program

    {

        static void Main(string[] args)

        {

            Task task=new Task(()=> Console.WriteLine("Write from another thread"));

            task.Start();

            Console.WriteLine("Main Thread");

            Console.ReadLine();        

        }

    }

}

 

两句输出的顺序是不一定的,但是很有可能是:

Main Thread

Write from another thread

也可以使用Task.Factory.StartNew方法,这个方易做图构造一个Task并且立刻开始运行,相当于将Task的构造函数和Start方法连在一起执行。

Task类还有一个构造函数可以接受Action<object>委托,用来向Action委托传递参数:

static void Main(string[] args)

{

    for (int i = 0; i < 5; i++)

    {

        Task t = new Task(obj => Console.WriteLine("Thread No " + obj), i);

        t.Start();

    }

    Console.ReadLine();  

}

输出的结果类似于:

Thread No 2

Thread No 1

Thread No 3

Thread No 0

Thread No 4

 

可以使用Task<T>类来获得返回值,T是返回值的类型,例如:

static void Main(string[] args)

{

     Task<int> t = new Task<int>(() =>

     {

         int s=0;

         for (int i = 0; i < 10000; i++)

             s += i;

         return s;

      });

      t.Start();

      Console.WriteLine("I'm computing");

      Console.WriteLine(t.Result);

      Console.ReadLine();

}

结果为:

I'm computing

49995000

在访问t.Result的时候,.net 会保证此时Task的代码已经执行完毕,Result已经获得,否则该线程会阻塞,直到Result计算完毕。

 

Task库提供了一种主动终止线程的方法,先创建一个CancellationTokenSource,将其Token属性通过Task构造函数传进去,在Task内部轮询token的IsCancellationReqeusted属性,如果检测到为true,则主动终止线程。在父线程内调用tokenSource的Cancel方法,可以终止线程。注意,这是线程主动终止自己的方法,必须在Task内的代码自己终止,.NET不会强行终止task线程,即使父线程调用了tokenSource的Cancel方法。

例如下面的代码,如果在else语句块内没有break语句,子线程是不会终止的。

using System;

using System.Threading;

using System.Threading.Tasks;

 

namespace TaskParallel

{

    class Program

    {

        static void Main(string[] args)

        {

            CancellationTokenSource tks = new CancellationTokenSource();

            CancellationToken token = tks.Token;

            long i = 0;

            Task task = new Task(() =>

            {              

                while (true)

                {

                    if (!token.IsCancellationRequested)

                        i++;

                    else

                    {

                        Console.WriteLine("Task is canceled, it looped "+i+" times");

                        break;

                    }

                }

            },token);

            task.Start();

            Console.WriteLine("Press Enter to Cancel task");

            Console.ReadLine();

            tks.Cancel();

            Console.ReadLine();

        }

    }

}

还可以通过CancellationToken的Register方法给token注册一个委托,当调用tokenSource的Cancel方法的时候,这个委托会被执行。这个委托是在调用Cancel方法的线程中执行的。

token.Register(() => { Console.WriteLine("Delegate Invoked"); });

 

要挂起当前线程,等待一个线程执行完成,可以使用执行线程的Wait()方法,Wait方法有一些重载方法,可以指定等待的时间等,例如:

static void Main(string[] args)

{

    Task t1 = new Task(() =>

    {

        Console.WriteLine("Task 1 Starts...");

        Thread.Sleep(3000);

        Console.WriteLine("Task1 Ends");

    });

    t1.Start();

    Task t2 = new Task(() =>

    {

        Console.WriteLine("Task2 Starts...");

        t1.Wait();

        Console.WriteLine("Task2 Ends");

    });

    Task t3 =

补充:Web开发 , ASP.Net ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,