• C# Task详解


    1、Task的优势

      ThreadPool相比Thread来说具备了很多优势,但是ThreadPool却又存在一些使用上的不方便。比如:
      ◆ ThreadPool不支持线程的取消、完成、失败通知等交互性操作;
      ◆ ThreadPool不支持线程执行的先后次序;
      以往,如果开发者要实现上述功能,需要完成很多额外的工作,现在,FCL中提供了一个功能更强大的概念:Task。Task在线程池的基础上进行了优化,并提供了更多的API。在FCL4.0中,如果我们要编写多线程程序,Task显然已经优于传统的方式。
      以下是一个简单的任务示例:

     1 using System;
     2 using System.Threading;
     3 using System.Threading.Tasks;
     4 
     5 namespace ConsoleApp1
     6 {
     7     class Program
     8     {
     9         static void Main(string[] args)
    10         {
    11             Task t = new Task(() =>
    12             {
    13                 Console.WriteLine("任务开始工作……");
    14                 //模拟工作过程
    15                 Thread.Sleep(5000);
    16             });
    17             t.Start();
    18             t.ContinueWith((task) =>
    19             {
    20                 Console.WriteLine("任务完成,完成时候的状态为:");
    21                 Console.WriteLine("IsCanceled={0}	IsCompleted={1}	IsFaulted={2}", task.IsCanceled, task.IsCompleted, task.IsFaulted);
    22             });
    23             Console.ReadKey();
    24         }
    25     }
    26 }

    2、Task的用法

    2.1、创建任务

    (一)无返回值的方式
    方式1:

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

    方式2:

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

    方式3:

    1   Task.Factory.StartNew(() => TaskMethod("Task 3")); 直接异步的方法 
    2   //或者
    3   var t3=Task.Factory.StartNew(() => TaskMethod("Task 3"));
    4   Task.WaitAll(t3);//等待所有任务结束
    5   //任务的状态:
    6   Start之前为:Running
    7   Start之后为:Running
     1 using System;
     2 using System.Threading;
     3 using System.Threading.Tasks;
     4 
     5 namespace ConsoleApp1
     6 {
     7     class Program
     8     {
     9         static void Main(string[] args)
    10         {
    11             var t1 = new Task(() => TaskMethod("Task 1"));
    12             var t2 = new Task(() => TaskMethod("Task 2"));
    13             t2.Start();
    14             t1.Start();
    15             Task.WaitAll(t1, t2);
    16             Task.Run(() => TaskMethod("Task 3"));
    17             Task.Factory.StartNew(() => TaskMethod("Task 4"));
    18             //标记为长时间运行任务,则任务不会使用线程池,而在单独的线程中运行。
    19             Task.Factory.StartNew(() => TaskMethod("Task 5"), TaskCreationOptions.LongRunning);
    20 
    21             #region 常规的使用方式
    22             Console.WriteLine("主线程执行业务处理.");
    23             //创建任务
    24             Task task = new Task(() =>
    25             {
    26                 Console.WriteLine("使用System.Threading.Tasks.Task执行异步操作.");
    27                 for (int i = 0; i < 10; i++)
    28                 {
    29                     Console.WriteLine(i);
    30                 }
    31             });
    32             //启动任务,并安排到当前任务队列线程中执行任务(System.Threading.Tasks.TaskScheduler)
    33             task.Start();
    34             Console.WriteLine("主线程执行其他处理");
    35             task.Wait();
    36             #endregion
    37 
    38             Thread.Sleep(TimeSpan.FromSeconds(1));
    39             Console.ReadLine();
    40         }
    41 
    42         static void TaskMethod(string name)
    43         {
    44             Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
    45                 name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
    46         }
    47     }
    48 }

    async/await的实现方式:

     1 using System;
     2 using System.Threading;
     3 using System.Threading.Tasks;
     4 
     5 namespace ConsoleApp1
     6 {
     7     class Program
     8     {
     9         async static void AsyncFunction()
    10         {
    11             await Task.Delay(1);
    12             Console.WriteLine("使用System.Threading.Tasks.Task执行异步操作.");
    13             for (int i = 0; i < 10; i++)
    14             {
    15                 Console.WriteLine(string.Format("AsyncFunction:i={0}", i));
    16             }
    17         }
    18 
    19         public static void Main()
    20         {
    21             Console.WriteLine("主线程执行业务处理.");
    22             AsyncFunction();
    23             Console.WriteLine("主线程执行其他处理");
    24             for (int i = 0; i < 10; i++)
    25             {
    26                 Console.WriteLine(string.Format("Main:i={0}", i));
    27             }
    28             Console.ReadLine();
    29         }
    30     }
    31 }

    (二)带返回值的方式
    方式4:

    1     Task<int> task = CreateTask("Task 1");
    2     task.Start(); 
    3     int result = task.Result;
     1 using System;
     2 using System.Threading;
     3 using System.Threading.Tasks;
     4 
     5 namespace ConsoleApp1
     6 {
     7     class Program
     8     {
     9         static Task<int> CreateTask(string name)
    10         {
    11             return new Task<int>(() => TaskMethod(name));
    12         }
    13 
    14         static void Main(string[] args)
    15         {
    16             TaskMethod("Main Thread Task");
    17             Task<int> task = CreateTask("Task 1");
    18             task.Start();
    19             int result = task.Result;
    20             Console.WriteLine("Task 1 Result is: {0}", result);
    21 
    22             task = CreateTask("Task 2");
    23             //该任务会运行在主线程中
    24             task.RunSynchronously();
    25             result = task.Result;
    26             Console.WriteLine("Task 2 Result is: {0}", result);
    27 
    28             task = CreateTask("Task 3");
    29             Console.WriteLine(task.Status);
    30             task.Start();
    31 
    32             while (!task.IsCompleted)
    33             {
    34                 Console.WriteLine(task.Status);
    35                 Thread.Sleep(TimeSpan.FromSeconds(0.5));
    36             }
    37 
    38             Console.WriteLine(task.Status);
    39             result = task.Result;
    40             Console.WriteLine("Task 3 Result is: {0}", result);
    41 
    42             #region 常规使用方式
    43             //创建任务
    44             Task<int> getsumtask = new Task<int>(() => Getsum());
    45             //启动任务,并安排到当前任务队列线程中执行任务(System.Threading.Tasks.TaskScheduler)
    46             getsumtask.Start();
    47             Console.WriteLine("主线程执行其他处理");
    48             //等待任务的完成执行过程。
    49             getsumtask.Wait();
    50             //获得任务的执行结果
    51             Console.WriteLine("任务执行结果:{0}", getsumtask.Result.ToString());
    52             #endregion
    53         }
    54 
    55         static int TaskMethod(string name)
    56         {
    57             Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
    58                 name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
    59             Thread.Sleep(TimeSpan.FromSeconds(2));
    60             return 42;
    61         }
    62 
    63         static int Getsum()
    64         {
    65             int sum = 0;
    66             Console.WriteLine("使用Task执行异步操作.");
    67             for (int i = 0; i < 100; i++)
    68             {
    69                 sum += i;
    70             }
    71             return sum;
    72         }
    73     }
    74 }

    async/await的实现:

     1 using System;
     2 using System.Threading.Tasks;
     3 
     4 namespace ConsoleApp1
     5 {
     6     class Program
     7     {
     8         public static void Main()
     9         {
    10             var ret1 = AsyncGetsum();
    11             Console.WriteLine("主线程执行其他处理");
    12             for (int i = 1; i <= 3; i++)
    13                 Console.WriteLine("Call Main()");
    14             int result = ret1.Result;                  //阻塞主线程
    15             Console.WriteLine("任务执行结果:{0}", result);
    16         }
    17 
    18         async static Task<int> AsyncGetsum()
    19         {
    20             await Task.Delay(1);
    21             int sum = 0;
    22             Console.WriteLine("使用Task执行异步操作.");
    23             for (int i = 0; i < 100; i++)
    24             {
    25                 sum += i;
    26             }
    27             return sum;
    28         }
    29     }
    30 }

    2.2、组合任务.ContinueWith

    简单Demo:

     1 using System;
     2 using System.Threading.Tasks;
     3 
     4 namespace ConsoleApp1
     5 {
     6     class Program
     7     {
     8         public static void Main()
     9         {
    10             //创建一个任务
    11             Task<int> task = new Task<int>(() =>
    12             {
    13                 int sum = 0;
    14                 Console.WriteLine("使用Task执行异步操作.");
    15                 for (int i = 0; i < 100; i++)
    16                 {
    17                     sum += i;
    18                 }
    19                 return sum;
    20             });
    21             //启动任务,并安排到当前任务队列线程中执行任务(System.Threading.Tasks.TaskScheduler)
    22             task.Start();
    23             Console.WriteLine("主线程执行其他处理");
    24             //任务完成时执行处理。
    25             Task cwt = task.ContinueWith(t =>
    26             {
    27                 Console.WriteLine("任务完成后的执行结果:{0}", t.Result.ToString());
    28             });
    29             task.Wait();
    30             cwt.Wait();
    31         }
    32     }
    33 }

    任务的串行:

     1 using System;
     2 using System.Collections.Concurrent;
     3 using System.Threading;
     4 using System.Threading.Tasks;
     5 
     6 namespace ConsoleApp1
     7 {
     8     class Program
     9     {
    10         static void Main(string[] args)
    11         {
    12             ConcurrentStack<int> stack = new ConcurrentStack<int>();
    13 
    14             //t1先串行
    15             var t1 = Task.Factory.StartNew(() =>
    16             {
    17                 stack.Push(1);
    18                 stack.Push(2);
    19             });
    20 
    21             //t2,t3并行执行
    22             var t2 = t1.ContinueWith(t =>
    23             {
    24                 int result;
    25                 stack.TryPop(out result);
    26                 Console.WriteLine("Task t2 result={0},Thread id {1}", result, Thread.CurrentThread.ManagedThreadId);
    27             });
    28 
    29             //t2,t3并行执行
    30             var t3 = t1.ContinueWith(t =>
    31             {
    32                 int result;
    33                 stack.TryPop(out result);
    34                 Console.WriteLine("Task t3 result={0},Thread id {1}", result, Thread.CurrentThread.ManagedThreadId);
    35             });
    36 
    37             //等待t2和t3执行完
    38             Task.WaitAll(t2, t3);
    39 
    40             //t7串行执行
    41             var t4 = Task.Factory.StartNew(() =>
    42             {
    43                 Console.WriteLine("当前集合元素个数:{0},Thread id {1}", stack.Count, Thread.CurrentThread.ManagedThreadId);
    44             });
    45             t4.Wait();
    46         }
    47     }
    48 }

    子任务:

     1 using System;
     2 using System.Threading.Tasks;
     3 
     4 namespace ConsoleApp1
     5 {
     6     class Program
     7     {
     8         public static void Main()
     9         {
    10             Task<string[]> parent = new Task<string[]>(state =>
    11             {
    12                 Console.WriteLine(state);
    13                 string[] result = new string[2];
    14                 //创建并启动子任务
    15                 new Task(() => { result[0] = "我是子任务1。"; }, TaskCreationOptions.AttachedToParent).Start();
    16                 new Task(() => { result[1] = "我是子任务2。"; }, TaskCreationOptions.AttachedToParent).Start();
    17                 return result;
    18             }, "我是父任务,并在我的处理过程中创建多个子任务,所有子任务完成以后我才会结束执行。");
    19             //任务处理完成后执行的操作
    20             parent.ContinueWith(t =>
    21             {
    22                 Array.ForEach(t.Result, r => Console.WriteLine(r));
    23             });
    24             //启动父任务
    25             parent.Start();
    26             //等待任务结束 Wait只能等待父线程结束,没办法等到父线程的ContinueWith结束
    27             //parent.Wait();
    28             Console.ReadLine();
    29 
    30         }
    31     }
    32 }

    动态并行(TaskCreationOptions.AttachedToParent) 父任务等待所有子任务完成后 整个任务才算完成

     1 using System;
     2 using System.Threading;
     3 using System.Threading.Tasks;
     4 
     5 namespace ConsoleApp1
     6 {
     7     class Node
     8     {
     9         public Node Left { get; set; }
    10         public Node Right { get; set; }
    11         public string Text { get; set; }
    12     }
    13 
    14 
    15     class Program
    16     {
    17         static Node GetNode()
    18         {
    19             Node root = new Node
    20             {
    21                 Left = new Node
    22                 {
    23                     Left = new Node
    24                     {
    25                         Text = "L-L"
    26                     },
    27                     Right = new Node
    28                     {
    29                         Text = "L-R"
    30                     },
    31                     Text = "L"
    32                 },
    33                 Right = new Node
    34                 {
    35                     Left = new Node
    36                     {
    37                         Text = "R-L"
    38                     },
    39                     Right = new Node
    40                     {
    41                         Text = "R-R"
    42                     },
    43                     Text = "R"
    44                 },
    45                 Text = "Root"
    46             };
    47             return root;
    48         }
    49 
    50         static void Main(string[] args)
    51         {
    52             Node root = GetNode();
    53             DisplayTree(root);
    54         }
    55 
    56         static void DisplayTree(Node root)
    57         {
    58             var task = Task.Factory.StartNew(() => DisplayNode(root),
    59                                             CancellationToken.None,
    60                                             TaskCreationOptions.None,
    61                                             TaskScheduler.Default);
    62             task.Wait();
    63         }
    64 
    65         static void DisplayNode(Node current)
    66         {
    67 
    68             if (current.Left != null)
    69                 Task.Factory.StartNew(() => DisplayNode(current.Left),
    70                                             CancellationToken.None,
    71                                             TaskCreationOptions.AttachedToParent,
    72                                             TaskScheduler.Default);
    73             if (current.Right != null)
    74                 Task.Factory.StartNew(() => DisplayNode(current.Right),
    75                                             CancellationToken.None,
    76                                             TaskCreationOptions.AttachedToParent,
    77                                             TaskScheduler.Default);
    78             Console.WriteLine("当前节点的值为{0};处理的ThreadId={1}", current.Text, Thread.CurrentThread.ManagedThreadId);
    79         }
    80     }
    81 }

    2.3、取消任务 CancellationTokenSource

     1 using System;
     2 using System.Threading;
     3 using System.Threading.Tasks;
     4 
     5 namespace ConsoleApp1
     6 {
     7     class Program
     8     {
     9         private static int TaskMethod(string name, int seconds, CancellationToken token)
    10         {
    11             Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
    12                 name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
    13             for (int i = 0; i < seconds; i++)
    14             {
    15                 Thread.Sleep(TimeSpan.FromSeconds(1));
    16                 if (token.IsCancellationRequested) return -1;
    17             }
    18             return 42 * seconds;
    19         }
    20 
    21         private static void Main(string[] args)
    22         {
    23             var cts = new CancellationTokenSource();
    24             var longTask = new Task<int>(() => TaskMethod("Task 1", 10, cts.Token), cts.Token);
    25             Console.WriteLine(longTask.Status);
    26             cts.Cancel();
    27             Console.WriteLine(longTask.Status);
    28             Console.WriteLine("First task has been cancelled before execution");
    29             cts = new CancellationTokenSource();
    30             longTask = new Task<int>(() => TaskMethod("Task 2", 10, cts.Token), cts.Token);
    31             longTask.Start();
    32             for (int i = 0; i < 5; i++)
    33             {
    34                 Thread.Sleep(TimeSpan.FromSeconds(0.5));
    35                 Console.WriteLine(longTask.Status);
    36             }
    37             cts.Cancel();
    38             for (int i = 0; i < 5; i++)
    39             {
    40                 Thread.Sleep(TimeSpan.FromSeconds(0.5));
    41                 Console.WriteLine(longTask.Status);
    42             }
    43 
    44             Console.WriteLine("A task has been completed with result {0}.", longTask.Result);
    45         }
    46     }
    47 }

    2.4、处理任务中的异常

    单个任务:

     1 using System;
     2 using System.Threading;
     3 using System.Threading.Tasks;
     4 
     5 namespace ConsoleApp1
     6 {
     7     class Program
     8     {
     9         static int TaskMethod(string name, int seconds)
    10         {
    11             Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
    12                 name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
    13             Thread.Sleep(TimeSpan.FromSeconds(seconds));
    14             throw new Exception("Boom!");
    15             return 42 * seconds;
    16         }
    17 
    18         static void Main(string[] args)
    19         {
    20             try
    21             {
    22                 Task<int> task = Task.Run(() => TaskMethod("Task 2", 2));
    23                 int result = task.GetAwaiter().GetResult();
    24                 Console.WriteLine("Result: {0}", result);
    25             }
    26             catch (Exception ex)
    27             {
    28                 Console.WriteLine("Task 2 Exception caught: {0}", ex.Message);
    29             }
    30             Console.WriteLine("----------------------------------------------");
    31             Console.WriteLine();
    32         }
    33     }
    34 }

    多个任务:

     1 using System;
     2 using System.Threading;
     3 using System.Threading.Tasks;
     4 
     5 namespace ConsoleApp1
     6 {
     7     class Program
     8     {
     9         static int TaskMethod(string name, int seconds)
    10         {
    11             Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
    12                 name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
    13             Thread.Sleep(TimeSpan.FromSeconds(seconds));
    14             throw new Exception(string.Format("Task {0} Boom!", name));
    15             return 42 * seconds;
    16         }
    17 
    18 
    19         public static void Main(string[] args)
    20         {
    21             try
    22             {
    23                 var t1 = new Task<int>(() => TaskMethod("Task 3", 3));
    24                 var t2 = new Task<int>(() => TaskMethod("Task 4", 2));
    25                 var complexTask = Task.WhenAll(t1, t2);
    26                 var exceptionHandler = complexTask.ContinueWith(t =>
    27                         Console.WriteLine("Result: {0}", t.Result),
    28                         TaskContinuationOptions.OnlyOnFaulted
    29                     );
    30                 t1.Start();
    31                 t2.Start();
    32                 Task.WaitAll(t1, t2);
    33             }
    34             catch (AggregateException ex)
    35             {
    36                 ex.Handle(exception =>
    37                 {
    38                     Console.WriteLine(exception.Message);
    39                     return true;
    40                 });
    41             }
    42         }
    43     }
    44 }

     async/await的方式:

     1 using System;
     2 using System.Threading;
     3 using System.Threading.Tasks;
     4 
     5 namespace ConsoleApp1
     6 {
     7     class Program
     8     {
     9         static async Task ThrowNotImplementedExceptionAsync()
    10         {
    11             throw new NotImplementedException();
    12         }
    13 
    14         static async Task ThrowInvalidOperationExceptionAsync()
    15         {
    16             throw new InvalidOperationException();
    17         }
    18 
    19         static async Task Normal()
    20         {
    21             await Fun();
    22         }
    23 
    24         static Task Fun()
    25         {
    26             return Task.Run(() =>
    27             {
    28                 for (int i = 1; i <= 10; i++)
    29                 {
    30                     Console.WriteLine("i={0}", i);
    31                     Thread.Sleep(200);
    32                 }
    33             });
    34         }
    35 
    36         static async Task ObserveOneExceptionAsync()
    37         {
    38             var task1 = ThrowNotImplementedExceptionAsync();
    39             var task2 = ThrowInvalidOperationExceptionAsync();
    40             var task3 = Normal();
    41 
    42 
    43             try
    44             {
    45                 //异步的方式
    46                 Task allTasks = Task.WhenAll(task1, task2, task3);
    47                 await allTasks;
    48                 //同步的方式
    49                 //Task.WaitAll(task1, task2, task3);
    50             }
    51             catch (NotImplementedException ex)
    52             {
    53                 Console.WriteLine("task1 任务报错!");
    54             }
    55             catch (InvalidOperationException ex)
    56             {
    57                 Console.WriteLine("task2 任务报错!");
    58             }
    59             catch (Exception ex)
    60             {
    61                 Console.WriteLine("任务报错!");
    62             }
    63 
    64         }
    65 
    66         public static void Main()
    67         {
    68             Task task = ObserveOneExceptionAsync();
    69             Console.WriteLine("主线程继续运行........");
    70             task.Wait();
    71         }
    72     }
    73 }

    2.5、Task.FromResult的应用

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Threading;
     4 using System.Threading.Tasks;
     5 
     6 namespace ConsoleApp1
     7 {
     8     class Program
     9     {
    10         static IDictionary<string, string> cache = new Dictionary<string, string>()
    11         {
    12             {"0001","A"},
    13             {"0002","B"},
    14             {"0003","C"},
    15             {"0004","D"},
    16             {"0005","E"},
    17             {"0006","F"},
    18         };
    19 
    20         public static void Main()
    21         {
    22             Task<string> task = GetValueFromCache("0006");
    23             Console.WriteLine("主程序继续执行。。。。");
    24             string result = task.Result;
    25             Console.WriteLine("result={0}", result);
    26 
    27         }
    28 
    29         private static Task<string> GetValueFromCache(string key)
    30         {
    31             Console.WriteLine("GetValueFromCache开始执行。。。。");
    32             string result = string.Empty;
    33             //Task.Delay(5000);
    34             Thread.Sleep(5000);
    35             Console.WriteLine("GetValueFromCache继续执行。。。。");
    36             if (cache.TryGetValue(key, out result))
    37             {
    38                 return Task.FromResult(result);
    39             }
    40             return Task.FromResult("");
    41         }
    42 
    43     }
    44 }

    2.6、使用IProgress实现异步编程的进程通知

      IProgress<in T>只提供了一个方法void Report(T value),通过Report方法把一个T类型的值报告给IProgress,然后IProgress<in T>的实现类Progress<in T>的构造函数接收类型为Action<T>的形参,通过这个委托让进度显示在UI界面中。

     1 using System;
     2 using System.Threading;
     3 using System.Threading.Tasks;
     4 
     5 namespace ConsoleApp1
     6 {
     7     class Program
     8     {
     9         static void DoProcessing(IProgress<int> progress)
    10         {
    11             for (int i = 0; i <= 100; ++i)
    12             {
    13                 Thread.Sleep(100);
    14                 if (progress != null)
    15                 {
    16                     progress.Report(i);
    17                 }
    18             }
    19         }
    20 
    21         static async Task Display()
    22         {
    23             //当前线程
    24             var progress = new Progress<int>(percent =>
    25             {
    26                 Console.Clear();
    27                 Console.Write("{0}%", percent);
    28             });
    29             //线程池线程
    30             await Task.Run(() => DoProcessing(progress));
    31             Console.WriteLine("");
    32             Console.WriteLine("结束");
    33         }
    34 
    35         public static void Main()
    36         {
    37             Task task = Display();
    38             task.Wait();
    39         }
    40     }
    41 }

    2.7、Factory.FromAsync的应用 (简APM模式(委托)转换为任务)(BeginXXX和EndXXX)

    带回调方式的

     1 using System;
     2 using System.Threading;
     3 using System.Threading.Tasks;
     4 
     5 namespace ConsoleApp1
     6 {
     7     class Program
     8     {
     9         private delegate string AsynchronousTask(string threadName);
    10 
    11         private static string Test(string threadName)
    12         {
    13             Console.WriteLine("Starting...");
    14             Console.WriteLine("Is thread pool thread: {0}", Thread.CurrentThread.IsThreadPoolThread);
    15             Thread.Sleep(TimeSpan.FromSeconds(2));
    16             Thread.CurrentThread.Name = threadName;
    17             return string.Format("Thread name: {0}", Thread.CurrentThread.Name);
    18         }
    19 
    20         private static void Callback(IAsyncResult ar)
    21         {
    22             Console.WriteLine("Starting a callback...");
    23             Console.WriteLine("State passed to a callbak: {0}", ar.AsyncState);
    24             Console.WriteLine("Is thread pool thread: {0}", Thread.CurrentThread.IsThreadPoolThread);
    25             Console.WriteLine("Thread pool worker thread id: {0}", Thread.CurrentThread.ManagedThreadId);
    26         }
    27 
    28         //执行的流程是 先执行Test--->Callback--->task.ContinueWith
    29         static void Main(string[] args)
    30         {
    31             AsynchronousTask d = Test;
    32             Console.WriteLine("Option 1");
    33             Task<string> task = Task<string>.Factory.FromAsync(
    34                 d.BeginInvoke("AsyncTaskThread", Callback, "a delegate asynchronous call"), d.EndInvoke);
    35 
    36             task.ContinueWith(t => Console.WriteLine("Callback is finished, now running a continuation! Result: {0}",
    37                 t.Result));
    38 
    39             while (!task.IsCompleted)
    40             {
    41                 Console.WriteLine(task.Status);
    42                 Thread.Sleep(TimeSpan.FromSeconds(0.5));
    43             }
    44             Console.WriteLine(task.Status);
    45 
    46         }
    47     }
    48 }

    不带回调方式的

     1 using System;
     2 using System.Threading;
     3 using System.Threading.Tasks;
     4 
     5 namespace ConsoleApp1
     6 {
     7     class Program
     8     {
     9         private delegate string AsynchronousTask(string threadName);
    10 
    11         private static string Test(string threadName)
    12         {
    13             Console.WriteLine("Starting...");
    14             Console.WriteLine("Is thread pool thread: {0}", Thread.CurrentThread.IsThreadPoolThread);
    15             Thread.Sleep(TimeSpan.FromSeconds(2));
    16             Thread.CurrentThread.Name = threadName;
    17             return string.Format("Thread name: {0}", Thread.CurrentThread.Name);
    18         }
    19 
    20         //执行的流程是 先执行Test--->task.ContinueWith
    21         static void Main(string[] args)
    22         {
    23             AsynchronousTask d = Test;
    24             Task<string> task = Task<string>.Factory.FromAsync(
    25                 d.BeginInvoke, d.EndInvoke, "AsyncTaskThread", "a delegate asynchronous call");
    26             task.ContinueWith(t => Console.WriteLine("Task is completed, now running a continuation! Result: {0}",
    27                 t.Result));
    28             while (!task.IsCompleted)
    29             {
    30                 Console.WriteLine(task.Status);
    31                 Thread.Sleep(TimeSpan.FromSeconds(0.5));
    32             }
    33             Console.WriteLine(task.Status);
    34 
    35         }
    36     }
    37 }

     1 //Task启动带参数和返回值的函数任务
     2 //下面的例子test2 是个带参数和返回值的函数。
     3 
     4 private int test2(object i)
     5 {
     6     this.Invoke(new Action(() =>
     7     {
     8         pictureBox1.Visible = true;
     9     }));
    10     System.Threading.Thread.Sleep(3000);
    11     MessageBox.Show("hello:" + i);
    12     this.Invoke(new Action(() =>
    13     {
    14         pictureBox1.Visible = false;
    15     }));
    16     return 0;
    17 }
    18 
    19 //测试调用
    20 private void call()
    21 {
    22     //Func<string, string> funcOne = delegate(string s){ return "fff"; };
    23     object i = 55;
    24     var t = Task<int>.Factory.StartNew(new Func<object, int>(test2), i);
    25 }
    26 
    27 //= 下载网站源文件例子 == == == == == == == == == == == ==
    28 //HttpClient 引用System.Net.Http
    29 private async Task< int> test2(object i)
    30 {
    31     this.Invoke(new Action(() =>
    32     {
    33         pictureBox1.Visible = true;
    34     }));
    35 
    36     HttpClient client = new HttpClient();
    37     var a = await client.GetAsync("http://www.baidu.com");
    38     Task<string> s = a.Content.ReadAsStringAsync();
    39     MessageBox.Show (s.Result);
    40 
    41     //System.Threading.Thread.Sleep(3000);
    42     //MessageBox.Show("hello:"+ i);
    43     this.Invoke(new Action(() =>
    44     {
    45         pictureBox1.Visible = false;
    46     }));
    47     return 0;
    48 }
    49 
    50 async private void call()
    51 {
    52     //Func<string, string> funcOne = delegate(string s){ return "fff"; };
    53     object i = 55;
    54     var t = Task<Task<int>>.Factory.StartNew(new Func<object, Task<int>>(test2), i);
    55 }
    56 
    57 //----------或者----------
    58 
    59 private async void test2()
    60 {
    61     this.Invoke(new Action(() =>
    62     {
    63         pictureBox1.Visible = true;
    64     }));
    65     HttpClient client = new HttpClient();
    66     var a = await client.GetAsync("http://www.baidu.com");
    67     Task<string> s = a.Content.ReadAsStringAsync();
    68     MessageBox.Show (s.Result);
    69     this.Invoke(new Action(() =>
    70     {
    71         pictureBox1.Visible = false;
    72     }));
    73 }
    74 
    75 private void call()
    76 {
    77     var t = Task.Run(new Action(test2));
    78     //相当于
    79     //Thread th= new Thread(new ThreadStart(test2));
    80     //th.Start();
    81 }
  • 相关阅读:
    擅用伪元素::before(:before)和::after(:after)
    CSS清除浮动float
    javascript:void(0) 含义
    js运算符的优先级
    js的Array的sort()排序方法
    js将字符串转化为数字
    mvc:一
    六:使用注解整合开发
    五、整合struts2和mybatis和spring
    08_动态sql
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/14282305.html
Copyright © 2020-2023  润新知