zoukankan      html  css  js  c++  java
  • Task2

    这篇文章是第一篇Task文章的继续,比较啰嗦,本人也是靠msdn文档来学习的;

    一、罗列一些属性

    1、TaskCanceledException 类  ,表示一个用于告知任务取消的异常。https://msdn.microsoft.com/zh-cn/library/system.threading.tasks.taskcanceledexception(v=vs.110).aspx

    2、TaskContinuationOptions  Flag枚举,创建的任务指定行为,https://msdn.microsoft.com/zh-cn/library/system.threading.tasks.taskcontinuationoptions(v=vs.110).aspx

    3、TaskCreationOptions Flag枚举,指定用于控制任务的创建和执行的可选行为的标志。https://msdn.microsoft.com/zh-cn/library/system.threading.tasks.taskcreationoptions(v=vs.110).aspx

    4、TaskStatus 枚举,表示 Task的生命周期中的当前阶段。https://msdn.microsoft.com/zh-cn/library/system.threading.tasks.taskstatus(v=vs.110).aspx

    二、UnWrap  创建一个代理 Task 表示异步操作的 TryExecuteTaskInline。展开,解包,如返回值是Task<Task<int>>==>Task<int>

     1 // Invoking individual tasks is straightforward
     2             Task<int> t1 = RemoteIncrement(0);
     3             Console.WriteLine("Started RemoteIncrement(0)");
     4 
     5             // Chain together the results of (simulated) remote operations.
     6             // The use of Unwrap() instead of .Result below prevents this thread from blocking while setting up this continuation chain.
     7             Task<int> t2 = RemoteIncrement(4)
     8                 // RemoteIncrement() returns Task<int> so no unwrapping is needed for the first continuation.
     9                 .ContinueWith(t => RemoteIncrement(t.Result))
    10                 // ContinueWith() returns Task<Task<int>>. Therefore unwrapping is needed.
    11                 .Unwrap().ContinueWith(t => RemoteIncrement(t.Result))    
    12                 .Unwrap().ContinueWith(t => RemoteIncrement(t.Result))    // and on it goes...
    13                 .Unwrap();
    14             Console.WriteLine("Started RemoteIncrement(...(RemoteIncrement(RemoteIncrement(4))...)");
    15 
    16             try
    17             {
    18                 t1.Wait();
    19                 Console.WriteLine("Finished RemoteIncrement(0)
    ");
    20 
    21                 t2.Wait();
    22                 Console.WriteLine("Finished RemoteIncrement(...(RemoteIncrement(RemoteIncrement(4))...)");
    23             }
    24             catch (AggregateException e)
    25             {
    26                 Console.WriteLine("A task has thrown the following (unexpected) exception:
    {0}", e);
    27             }
    28 
    29             Console.ReadKey();
    30 //结果:
    31 //Started RemoteIncrement(0)
    32 //Started RemoteIncrement(...(RemoteIncrement(RemoteIncrement(4))...)
    33 //Thread=10, Next=1
    34 //Finished RemoteIncrement(0)
    35 
    36 //Thread=11, Next=5
    37 //Thread=12, Next=6
    38 //Thread=11, Next=7
    39 //Thread=10, Next=8
    40 //Finished RemoteIncrement(...(RemoteIncrement(RemoteIncrement(4))...)
    View Code

    三、TaskCompletionSource  

    TaskCompletionSource 表示未绑定到委托的 Task<TResult> 的制造者方,并通过 Task 属性提供对使用者方的访问值并且通过TrySetResult方法可以设置Task的返回值。         task.IsFaulted 只有在ContinueWith里面才会等待任务执行完

     1  static public class Connector
     2     {
     3         /// <summary>
     4         /// begin connect
     5         /// </summary>
     6         /// <param name="endPoint"></param>
     7         /// <exception cref="ArgumentNullException">endPoint is null</exception>
     8         static public Task<Socket> Connect(EndPoint endPoint)
     9         {
    10             if (endPoint == null) throw new ArgumentNullException("endPoint");
    11 
    12             var source = new TaskCompletionSource<Socket>();
    13             var socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
    14 
    15             var e = new SocketAsyncEventArgs();
    16             e.UserToken = new Tuple<TaskCompletionSource<Socket>, Socket>(source, socket);
    17             e.RemoteEndPoint = endPoint;
    18             e.Completed += OnCompleted;
    19 
    20             bool completed = true;
    21             try { completed = socket.ConnectAsync(e); }
    22             catch (Exception ex) { source.TrySetException(ex); }
    23             if (!completed) ThreadPool.QueueUserWorkItem(_ => OnCompleted(null, e));
    24 
    25             return source.Task;
    26         }
    27         /// <summary>
    28         /// connect completed
    29         /// </summary>
    30         /// <param name="sender"></param>
    31         /// <param name="e"></param>
    32         static private void OnCompleted(object sender, SocketAsyncEventArgs e)
    33         {
    34             var t = e.UserToken as Tuple<TaskCompletionSource<Socket>, Socket>;
    35             var source = t.Item1;
    36             var socket = t.Item2;
    37             var error = e.SocketError;
    38 
    39             e.UserToken = null;
    40             e.Completed -= OnCompleted;
    41             e.Dispose();
    42 
    43             if (error != SocketError.Success)
    44             {
    45                 socket.Close();
    46                 source.TrySetException(new SocketException((int)error));
    47                 return;
    48             }
    49 
    50             source.TrySetResult(socket);
    51         }
    52     }
    View Code
     1   TaskCompletionSource<int> tcs1 = new TaskCompletionSource<int>();
     2             Task<int> t1 = tcs1.Task;
     3             // Start a background task that will complete tcs1.Task
     4             Task.Factory.StartNew(() =>
     5             {
     6                 Thread.Sleep(2000);
     7                 tcs1.TrySetResult(15);
     8             });
     9             // The attempt to get the result of t1 blocks the current thread until the completion source gets signaled.
    10             // It should be a wait of ~2000 ms.
    11             Stopwatch sw = Stopwatch.StartNew();
    12             int result = t1.Result;//获取结果的时候必须等待操作完成
    13             sw.Stop();
    14             Console.WriteLine("(ElapsedTime={0}): t1.Result={1} (expected 15) ", sw.ElapsedMilliseconds, result);
    15 
    16             // Alternatively, an exception can be manually set on a TaskCompletionSource.Task
    17             TaskCompletionSource<int> tcs2 = new TaskCompletionSource<int>();
    18             Task<int> t2 = tcs2.Task;
    19 
    20             // Start a background Task that will complete tcs2.Task with an exception
    21             Task.Factory.StartNew(() =>
    22             {
    23                 Thread.Sleep(1000);
    24 
    25                 //tcs2.SetException(new InvalidOperationException("SIMULATED EXCEPTION"));
    26                 //出现了异常,已被系统处理,但是下面获取Result属性的时候肯定出错
    27                 tcs2.TrySetException(new InvalidOperationException("SIMULATED EXCEPTION"));
    28             });
    29 
    30             // The attempt to get the result of t2 blocks the current thread until the completion source gets signaled with either a result or an exception.
    31             // In either case it should be a wait of ~1000 ms.
    32             //sw = Stopwatch.StartNew();
    33             //解决异常1  调用 Task 的 Wait或者 Task.Result 方法时使用 try-catch 捕获异常:
    34             //try
    35             //{
    36             //    result = t2.Result;//因为TrySetException,获取结果会抛错
    37 
    38             //    Console.WriteLine("t2.Result succeeded. THIS WAS NOT EXPECTED.");
    39             //}
    40             //catch (AggregateException e)
    41             //{
    42             //    Console.Write("(ElapsedTime={0}): ", sw.ElapsedMilliseconds);
    43             //    Console.WriteLine("The following exceptions have been thrown by t2.Result: (THIS WAS EXPECTED)");
    44             //    for (int j = 0; j < e.InnerExceptions.Count; j++)
    45             //    {
    46             //        Console.WriteLine("
    -------------------------------------------------
    {0}", e.InnerExceptions[j].ToString());
    47             //    }
    48             //}
    49 
    50             //解决异常2 在 Task 的 ContinueWith 方法中读取 Task 的 IsFaulted 属性是否出错:
    51             t2.ContinueWith(task =>
    52             {
    53                 //task是上一个任务的结果, task.IsFaulted是判断有没有错误;如果不在ContinueWith里面或者在外面不用T2.Wait执行完,结果可能不
    54                 //正确,因为IsFaulted属性不会阻塞线程的, 直接判断任务代码还没出现错误都是false,没有出错
    55                 if (task.IsFaulted)
    56                 {
    57                     Console.WriteLine(task.Exception.GetBaseException());
    58                     Console.WriteLine("出现了异常,已被系统处理,但是获取Result属性的时候肯定出错");
    59                     Console.WriteLine(task.Result);
    60                 }
    61                 else
    62                 {
    63                     //没有异常才获取结果,要不然会抛错
    64                     Console.WriteLine(task.Result);
    65                 }
    66             });
    67             Console.ReadKey();
    View Code

    四、TaskFactory

    在大多数情况下,我们无需实例化一个新 TaskFactory 实例。 相反,可以使用 Task.Factory 属性,它返回一个工厂对象,将使用默认值。 然后可以调用其方法来启动新任务或定义任务延续。

    //想等待多个任务就用Task数组,使用Task.Await或者Task.Factory.ContinueWhenAll()

    //创建一个任务,在数组中的任务之一通过调用完成后开始 ContinueWhenAny 方法。
    //创建一个任务,在数组中的所有任务已都完成通过调用开始 ContinueWhenAll 方法。

     1 //TaskFactory 类
     2 Task[] tasks = new Task[2];
     3             String[] files = null;
     4             String[] dirs = null;
     5             String docsDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
     6             tasks[0] = Task.Factory.StartNew(() => { Thread.Sleep(3000); files = Directory.GetFiles(docsDirectory); });
     7             tasks[1] = Task.Factory.StartNew(() => dirs = Directory.GetDirectories(docsDirectory));
     8             Console.WriteLine(files.Length);//不会等待的,报空异常
     9             Task.Factory.ContinueWhenAll(tasks, completedTasks =>
    10             {
    11                 Console.WriteLine("{0} contains: ", docsDirectory);
    12                 Console.WriteLine("   {0} subdirectories", dirs.Length);
    13                 Console.WriteLine("   {0} files", files.Length);
    14             });
    15             Console.ReadKey();
    TaskFactory
                Task<string[]>[] tasks = new Task<string[]>[2];
                string docsDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                tasks[0] = Task<string[]>.Factory.StartNew(() => Directory.GetFiles(docsDirectory));
                tasks[1] = Task<string[]>.Factory.StartNew(() => Directory.GetDirectories(docsDirectory));
                Task.Factory.ContinueWhenAll(tasks, completedTasks =>
                {
                    Console.WriteLine("{0} contains: ", docsDirectory);
                    Console.WriteLine("   {0} subdirectories", tasks[1].Result.Length);
                    Console.WriteLine("   {0} files", tasks[0].Result.Length);
                });
                Console.ReadKey();
    

      

  • 相关阅读:
    Tomcat全攻略
    JAVA必备——13个核心规范
    利用Node.js实现模拟Session验证的登陆
    Android中关于JNI 的学习(六)JNI中注冊方法的实现
    pomelo源代码分析(一)
    怎样解决栈溢出
    String,StringBuffer与StringBuilder的差别??
    ERWin 7.1 和7.2 的官方FTP下载地址
    C/C++中各种类型int、long、double、char表示范围(最大最小值)
    下拉刷新,上拉装载许多其他ListView
  • 原文地址:https://www.cnblogs.com/entclark/p/8047323.html
Copyright © 2011-2022 走看看