码农之家

专注优质代码开发,为软件行业发展贡献力量

C# Task详解

1.ThreadPool相比Thread来说具备了很多优势,但是ThreadPool却又存在一些使用上的不方便。比如:

  ◆ ThreadPool不支持线程的取消、完成、失败通知等交互性操作;

  ◆ ThreadPool不支持线程执行的先后次序;

  以往,如果开发者要实现上述功能,需要完成很多额外的工作,现在,FCL中提供了一个功能更强大的概念:Task。Task在线程池的基础上进行了优化,并提供了更多的API。在FCL4.0中,如果我们要编写多线程程序,Task显然已经优于传统的方式。

  以下是一个简单的任务示例:

using System;

using System.Threading;

using System.Threading.Tasks;


namespace ConsoleApp1

{

    class Program

    {

        static void Main(string[] args)

        {

            Task t = new Task(() =>

            {

                Console.WriteLine("任务开始工作……");

                //模拟工作过程

                Thread.Sleep(5000);

            });

            t.Start();

            t.ContinueWith((task) =>

            {

                Console.WriteLine("任务完成,完成时候的状态为:");

                Console.WriteLine("IsCanceled={0}\tIsCompleted={1}\tIsFaulted={2}", task.IsCanceled, task.IsCompleted, task.IsFaulted);

            });

            Console.ReadKey();

        }

    }

}

2、Task的用法

  2.1、创建任务

  (一)无返回值的方式

  方式1:

   var t1 = new Task(() => TaskMethod("Task 1"));
  t1.Start();
  Task.WaitAll(t1);//等待所有任务结束   注:任务的状态:
  Start之前为:Created
  Start之后为:WaitingToRun

     方式2:

  Task.Run(() => TaskMethod("Task 2"));

     方式3:

     

     Task.Factory.StartNew(() => TaskMethod("Task 3")); 直接异步的方法 

  //或者

  var t3=Task.Factory.StartNew(() => TaskMethod("Task 3"));

  Task.WaitAll(t3);//等待所有任务结束

  //任务的状态:

  Start之前为:Running

  Start之后为:Running


        using System;

        using System.Threading;

        using System.Threading.Tasks;

        

        namespace ConsoleApp1

        {

            class Program

            {

                static void Main(string[] args)

                {

                    var t1 = new Task(() => TaskMethod("Task 1"));

                    var t2 = new Task(() => TaskMethod("Task 2"));

                    t2.Start();

                    t1.Start();

                    Task.WaitAll(t1, t2);

                    Task.Run(() => TaskMethod("Task 3"));

                    Task.Factory.StartNew(() => TaskMethod("Task 4"));

                    //标记为长时间运行任务,则任务不会使用线程池,而在单独的线程中运行。

                    Task.Factory.StartNew(() => TaskMethod("Task 5"), TaskCreationOptions.LongRunning);

        

                    #region 常规的使用方式

                    Console.WriteLine("主线程执行业务处理.");

                    //创建任务

                    Task task = new Task(() =>

                    {

                        Console.WriteLine("使用System.Threading.Tasks.Task执行异步操作.");

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

                        {

                            Console.WriteLine(i);

                        }

                    });

                    //启动任务,并安排到当前任务队列线程中执行任务(System.Threading.Tasks.TaskScheduler)

                    task.Start();

                    Console.WriteLine("主线程执行其他处理");

                    task.Wait();

                    #endregion

        

                    Thread.Sleep(TimeSpan.FromSeconds(1));

                    Console.ReadLine();

                }

        

                static void TaskMethod(string name)

                {

                    Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",

                        name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);

                }

            }

        }


       async/await的实现方式:

  

        using System;

        using System.Threading;

        using System.Threading.Tasks;

        

        namespace ConsoleApp1

        {

            class Program

            {

                async static void AsyncFunction()

                {

                    await Task.Delay(1);

                    Console.WriteLine("使用System.Threading.Tasks.Task执行异步操作.");

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

                    {

                        Console.WriteLine(string.Format("AsyncFunction:i={0}", i));

                    }

                }

        

                public static void Main()

                {

                    Console.WriteLine("主线程执行业务处理.");

                    AsyncFunction();

                    Console.WriteLine("主线程执行其他处理");

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

                    {

                        Console.WriteLine(string.Format("Main:i={0}", i));

                    }

                    Console.ReadLine();

                }

            }

        }


    (二)带返回值的方式

      方式4:

       Task<int> task = CreateTask("Task 1");

  task.Start(); 

  int result = task.Result;

      

        using System;

        using System.Threading;

        using System.Threading.Tasks;

        

        namespace ConsoleApp1

        {

            class Program

            {

                static Task<int> CreateTask(string name)

                {

                    return new Task<int>(() => TaskMethod(name));

                }

        

                static void Main(string[] args)

                {

                    TaskMethod("Main Thread Task");

                    Task<int> task = CreateTask("Task 1");

                    task.Start();

                    int result = task.Result;

                    Console.WriteLine("Task 1 Result is: {0}", result);

        

                    task = CreateTask("Task 2");

                    //该任务会运行在主线程中

                    task.RunSynchronously();

                    result = task.Result;

                    Console.WriteLine("Task 2 Result is: {0}", result);

        

                    task = CreateTask("Task 3");

                    Console.WriteLine(task.Status);

                    task.Start();

        

                    while (!task.IsCompleted)

                    {

                        Console.WriteLine(task.Status);

                        Thread.Sleep(TimeSpan.FromSeconds(0.5));

                    }

        

                    Console.WriteLine(task.Status);

                    result = task.Result;

                    Console.WriteLine("Task 3 Result is: {0}", result);

        

                    #region 常规使用方式

                    //创建任务

                    Task<int> getsumtask = new Task<int>(() => Getsum());

                    //启动任务,并安排到当前任务队列线程中执行任务(System.Threading.Tasks.TaskScheduler)

                    getsumtask.Start();

                    Console.WriteLine("主线程执行其他处理");

                    //等待任务的完成执行过程。

                    getsumtask.Wait();

                    //获得任务的执行结果

                    Console.WriteLine("任务执行结果:{0}", getsumtask.Result.ToString());

                    #endregion

                }

        

                static int TaskMethod(string name)

                {

                    Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",

                        name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);

                    Thread.Sleep(TimeSpan.FromSeconds(2));

                    return 42;

                }

        

                static int Getsum()

                {

                    int sum = 0;

                    Console.WriteLine("使用Task执行异步操作.");

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

                    {

                        sum += i;

                    }

                    return sum;

                }

            }

        }


       async/await的实现:

       

        using System;

        using System.Threading.Tasks;

        

        namespace ConsoleApp1

        {

            class Program

            {

                public static void Main()

                {

                    var ret1 = AsyncGetsum();

                    Console.WriteLine("主线程执行其他处理");

                    for (int i = 1; i <= 3; i++)

                        Console.WriteLine("Call Main()");

                    int result = ret1.Result;                  //阻塞主线程

                    Console.WriteLine("任务执行结果:{0}", result);

                }

        

                async static Task<int> AsyncGetsum()

                {

                    await Task.Delay(1);

                    int sum = 0;

                    Console.WriteLine("使用Task执行异步操作.");

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

                    {

                        sum += i;

                    }

                    return sum;

                }

            }

        }


0 评论数