zoukankan      html  css  js  c++  java
  • 多线程的几种方式

    简单的利用线程池启动线程
     1         /// <summary>
     2         /// 简单的利用线程此启动线程
     3         /// </summary>
     4         public static void NewMethod1()
     5         {
     6             //只需要方法需要执行的方法就会启动线程池的的一个线程,不需要显示启动
     7             ThreadPool.UnsafeQueueUserWorkItem(new ThreadTest2().Task, 55);
     8 
     9             Debug.WriteLine(Thread.CurrentThread.ManagedThreadId + " Main: " + name);
    10 
    11         }
    12 
    13         public void Task(Object obj)
    14         {
    15             Debug.WriteLine(Thread.CurrentThread.ManagedThreadId + " Thread: " + obj + name);
    16         }
    执行上下文 支持为线程设置环境上下文
     1 public static void NewMethod2()
     2         {
     3             //在初始线程中设置逻辑调用上下文数据,会流向辅助线程
     4             CallContext.LogicalSetData("Name", "Jeffrey");
     5 
     6             ThreadPool.QueueUserWorkItem(statue =>
     7             {
     8                 //从辅助线程中确实拿到了数据上下文的数据
     9                 Console.WriteLine("Name={0}", CallContext.LogicalGetData("Name"));
    10             });
    11 
    12             //取消执行上下文在异步线程之间的流动。
    13             ExecutionContext.SuppressFlow();
    14 
    15             ThreadPool.QueueUserWorkItem(statue =>
    16             {
    17                 Console.WriteLine("Name={0}", CallContext.LogicalGetData("Name"));
    18             });
    19 
    20             //恢复执行上下文在异步线程之间的流动。
    21             ExecutionContext.RestoreFlow();
    22             Console.ReadKey();
    23         }
    协作是取消,支持在初始线程中中断辅助线程的生命, 并设置回调方法
     1 /// <summary>
     2         /// 协作是取消,支持在初始线程中中断辅助线程的生命
     3         /// </summary>
     4         public static void NewMethod3()
     5         {
     6             // 这个类就是控制辅助线程的终止的
     7             CancellationTokenSource cts = new CancellationTokenSource();
     8 
     9             ThreadPool.QueueUserWorkItem(o => Count(cts.Token, 100)); //这里传递了一个参数过去
    10 
    11             Debug.WriteLine("this");
    12             Thread.Sleep(1000);
    13             //通过调用这个方法来终止辅助线程的生命
    14             cts.Cancel();
    15         }
    16 
    17         private static void Count(CancellationToken token, int countTo)
    18         {
    19             for (Int32 count = 0; count < countTo; count++)
    20             {
    21                 //通过这个判断在初始线程中是否终止了改线程的生命
    22                 if (token.IsCancellationRequested)
    23                 {
    24                     Debug.WriteLine("Count is cancelled");
    25                     break;
    26                 }
    27 
    28                 Debug.WriteLine(count);
    29                 Thread.Sleep(100);
    30             }
    31             Debug.WriteLine("Count is done");
    32 
    33         }
    34 
    35 
    36         /// <summary>
    37         /// 可以为辅助线程停止定义回调方法
    38         /// </summary>
    39         public static void NewMethod31()
    40         {
    41             var cts1 = new CancellationTokenSource();
    42             //为cts1 注册一个辅助线程停止的回调方法
    43             cts1.Token.Register(() => { Debug.WriteLine("this 1"); });
    44 
    45 
    46             var cts2 = new CancellationTokenSource();
    47             //为cts2 注册一个辅助线程停止的回调方法
    48             ThreadPool.QueueUserWorkItem(o => { Count(cts2.Token, 10); });
    49             cts2.Token.Register(() => { Debug.WriteLine("this 2"); });
    50 
    51             //为cts1 或 cts2 注册一个辅助线程停止的回调方法
    52             var cts3 = CancellationTokenSource.CreateLinkedTokenSource(cts1.Token, cts2.Token);
    53             cts3.Token.Register(() => { Debug.WriteLine("this 3"); });
    54 
    55             cts2.Cancel();
    56 
    57             Debug.WriteLine("cts1: " + cts1.IsCancellationRequested + " cts2: " + cts2.IsCancellationRequested + " cts3: " + cts3.IsCancellationRequested);
    58 
    59         }
    Task 表示一个可以返回值的异步操作。
     1  public static void NewMethod4()
     2         {
     3             // Task接受一个带返回值的delegate 
     4             Task<Int32> t = new Task<Int32>((n => Sum((Int32)n)), 10000);
     5             //将任务放置到线程队列当中
     6             t.Start();
     7             //t.Wait();
     8             //Console.WriteLine(t.Result);
     9             //这种方式不会造成堵塞,在Task执行完毕的时候,就会启动这个任务
    10             t.ContinueWith(task => { Console.WriteLine(t.Result); });
    11             Console.WriteLine("this");
    12             Console.ReadKey();
    13         }
    14 
    15         private static Int32 Sum(Int32 n)
    16         {
    17             Int32 sum = 0;
    18             for (; n > 0; n--)
    19             {
    20                 checked { sum += n; };
    21             }
    22             return sum;
    23         }
    支持协作式的 Task操作
     1 /// <summary>
     2         /// 支持协作式的 Task操作
     3         /// </summary>
     4         public static void NewMethod41()
     5         {
     6             CancellationTokenSource cts = new CancellationTokenSource();
     7             Task<Int32> t = new Task<Int32>((() => Sum(cts.Token, 10000)), cts.Token);
     8             t.Start();
     9             cts.Cancel();
    10 
    11             try
    12             {
    13                 Debug.WriteLine(t.Result);
    14             }
    15             catch (AggregateException x)
    16             {
    17                 x.Handle(e => e is OperationCanceledException);
    18                 Debug.WriteLine("Exception");
    19             }
    20 
    21         }
    22 
    23         private static int Sum(CancellationToken ct, int n)
    24         {
    25             int sum = 0;
    26             for (; n > 0; n--)
    27             {
    28                 ct.ThrowIfCancellationRequested();
    29                 checked { sum += n; };
    30             }
    31             return sum;
    32         }
    添加子Task
     1 /// <summary> 
     2         ///  添加子Task
     3         /// </summary>
     4         public static void NewMethod42()
     5         {
     6             Task<Int32[]> parent = new Task<Int32[]>(() =>
     7             {
     8                 var results = new Int32[3];
     9                 Task task1 = new Task(() => results[0] = Sum(10000), TaskCreationOptions.AttachedToParent);
    10                 task1.Start();
    11                 Task task2 = new Task(() => results[1] = Sum(10000), TaskCreationOptions.AttachedToParent);
    12                 task2.Start();
    13                 Task task3 = new Task(() => results[2] = Sum(10000), TaskCreationOptions.AttachedToParent);
    14                 task3.Start();
    15                 Console.WriteLine(task1.Id);
    16                 Console.WriteLine("Thread status: " + task1.Status);
    17                 Console.WriteLine(task2.Id);
    18                 Console.WriteLine(task3.Id);
    19 
    20                 return results;
    21             });
    22             Console.WriteLine("parent: " + parent.Id);
    23             Console.WriteLine("parent status" + parent.Status);
    24             var cwt = parent.ContinueWith(parentTask => Array.ForEach(parentTask.Result, Console.WriteLine));
    25             parent.Start();
    26             Console.WriteLine("parent status" + parent.Status);
    27             Console.ReadKey();
    28         }
    TaskFactory
    /// <summary>
            /// TaskFactory 
            /// </summary>
            public static void NewMethod43()
            {
                Task parent = new Task(() =>
                {
                    var cts = new CancellationTokenSource();
                    var tf = new TaskFactory<Int32>(cts.Token, TaskCreationOptions.AttachedToParent,
                        TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
    
                    var childTasks = new[]
                    {
                      tf.StartNew(()=>Sum(cts.Token, 10000)),
                      tf.StartNew(()=>Sum(cts.Token, 20000)),  
                      tf.StartNew(()=>Sum(cts.Token, Int32.MaxValue))  
                    };
    
                    for (Int32 task = 0; task < childTasks.Length; task++)
                    {
                        childTasks[task].ContinueWith(t => cts.Cancel(), TaskContinuationOptions.OnlyOnFaulted);
                    }
    
                    tf.ContinueWhenAll(
                        childTasks,
                        completedTasks => completedTasks.Where(t => !t.IsFaulted && !t.IsCanceled).Max(t => t.Result),
                        CancellationToken.None
                        ).ContinueWith(
                            t => Console.WriteLine(t.Result),
                            TaskContinuationOptions.ExecuteSynchronously
                        );
    
                });
                parent.ContinueWith(p =>
                {
                    StringBuilder sb = new StringBuilder(Environment.NewLine);
                    foreach (var e in p.Exception.Flatten().InnerExceptions)
                        sb.Append(e.GetType().ToString());
                    Debug.WriteLine(sb.ToString());
    
                }, TaskContinuationOptions.OnlyOnFaulted);
    
                parent.Start();
            }
  • 相关阅读:
    POJ 3672 水题......
    POJ 3279 枚举?
    STL
    241. Different Ways to Add Parentheses
    282. Expression Add Operators
    169. Majority Element
    Weekly Contest 121
    927. Three Equal Parts
    910. Smallest Range II
    921. Minimum Add to Make Parentheses Valid
  • 原文地址:https://www.cnblogs.com/zhanhengzong/p/2813234.html
Copyright © 2011-2022 走看看