zoukankan      html  css  js  c++  java
  • 线程线程池委托taskasync/await

    如标题,这是.net发展异步的一个路线

    记录下备忘起来

     线程(Thread)

     Thread thread = new Thread(new ThreadStart(Method));//threadStart创建多线程(无参数)---〉 thread.Start();//执行

    Thread thread = new Thread(new ParameterizedThreadStart(Method)); //ParameterizedThreadStart 帮顶有参数的异步方法----〉thread.Start(参数)

    Thread有一个属性IsBackground,通过把此属性设置为true,就可以把线程设置为后台线程,thread.start方法启动默认是前台线程。

    Thread.Abort()终止线程并引发 ThreadAbortException异常,Thread.ResetAbort()方法取消终止,继续执行。

     线程池(ThreadPool)

     分工作者线程和I/O线程

    ThreadPool线程池中包含有两个静态方法可以直接启动工作者线程:
    一为 ThreadPool.QueueUserWorkItem(WaitCallback)
    二为 ThreadPool.QueueUserWorkItem(WaitCallback,Object) 

    先把WaitCallback委托指向一个带有Object参数的无返回值方法,再使用 ThreadPool.QueueUserWorkItem(WaitCallback) 就可以异步启动此方法,此时异步方法的参数被视为null 。 object对象作为参数传送到回调函数中

     委托是最灵活的工作者线程,见委托时间介绍

     task(基于任务的编程模型,简化了异步开发,比线程性能优越,任务调用了更低限度的线程池,可以替代老旧thread,但它同工作者线程池一样不适合运行较长时间的任务,如果需要的话则使用任务工厂的longrunning选项,即可告诉任务调度一个新的线程,类似直接new thread不鸟线程池)

     //第一种方式开启,created状态,任务在这个状态时才能使用start()方法让任务进入排队运行,就是第二种方式。

    2         var task1 = new Task(() =>
    3         {
    4             Run1();
    5         });


    //第二种方式开启,直接跳过第一步created状态,进入等待运行状态
    var task2 = Task.Factory.StartNew(() =>
    2             {
    3                 Run2();
    4             });
      Task.WaitAll(task1, task2);//并行执行

    取消标记”叫做CancellationTokenSource.Token,在创建task的时候传入此参数,就可以将主线程和任务相 关联,然后在任务中设置“取消信号“叫做ThrowIfCancellationRequested来等待主线程使用Cancel来通知,一旦cancel被调用。task将会 抛出OperationCanceledException来中断此任务的执行,最后将当前task的Status的IsCanceled属性设为true。

    获取返回值 

     这里t1任务执行完毕后,使用continuewith开始第二个任务(回调另一个方法),因为task并没有提供回调事件。

    //获取返回值第一种task<T>
    var t1 = Task.Factory.StartNew<List<string>>(() => { return Run1(); });
    t1.Wait();t1.result

    //获取返回值第二种
    var t1 = Task.Factory.StartNew<List<string>>(() => { return Run1(); });

            var t2 = t1.ContinueWith((i) =>  //Continuewith 串行执行,waitall并行执行
             {
                 Console.WriteLine("t1集合中返回的个数:" + string.Join(",", i.Result));
             });

    async/await (简化异步操作,不需要回掉函数而是用顺序编程)

     // Signature specifies Task<TResult>

    async Task<int> TaskOfTResult_MethodAsync()
    {
        int hours;
        // . . .
        
    // Return statement specifies an integer result.
        return hours;
    }

    // Calls to TaskOfTResult_MethodAsync
    Task<int> returnedTaskTResult = TaskOfTResult_MethodAsync();
    int intResult = await returnedTaskTResult;
    // or, in a single statement
    int intResult = await TaskOfTResult_MethodAsync();


    // Signature specifies Task
    async Task Task_MethodAsync()
    {
        // . . .
        
    // The method has no return statement.  
    }

    // Calls to Task_MethodAsync
    Task returnedTask = Task_MethodAsync();
    await returnedTask;
    // or, in a single statement
    await Task_MethodAsync();

    任务工厂 static void Main(string[] args        {

                CancellationTokenSource cts = new CancellationTokenSource();
                //cts可以共享给任务工厂,同时取消一组任务
                TaskFactory taskFactory = new TaskFactory();
                Task[] tasks = new Task[]
                    {
                        taskFactory.StartNew(() => Add(cts.Token)),
                        taskFactory.StartNew(() => Add(cts.Token)),
                        taskFactory.StartNew(() => Add(cts.Token))
                    };
                //CancellationToken.None指示TasksEnded回调不能被取消
                taskFactory.ContinueWhenAll(tasks, TasksEnded, CancellationToken.None);
                Console.ReadKey();//等待按键取消任务
                cts.Cancel();
                Console.ReadKey();
            }
            
            static void TasksEnded(Task[] tasks)
            {
                Console.WriteLine("所有任务已完成!");
            }

     static int Add(CancellationToken ct) { Console.WriteLine("任务开始……");
    int result =0;
    while (!ct.IsCancellationRequested) { result++; Thread.Sleep(1000); } return result; } 

    下面是父子任务模式

    using System;
    using System.Threading;
    using System.Threading.Tasks;
    public class Program {
        private static Int32 Sum(Int32 n)
        {
            Int32 sum = 0;
            for (; n > 0; n--)
            checked { sum += n; } 
            return sum;
        }
    
        public static void Main() {
    
            Task<int32[]> parent = new Task<int32[]>(() => {
                var results = new Int32[3];   // 创建一个数组存储结果
    
                // 创建三个子任务,并进入执行状态
                new Task(() => results[0] = Sum(100), 
                    TaskCreationOptions.AttachedToParent).Start();
                new Task(() => results[1] = Sum(200), 
                    TaskCreationOptions.AttachedToParent).Start();
                new Task(() => results[2] = Sum(300), 
                    TaskCreationOptions.AttachedToParent).Start();
    
                // 返回结果集
                return results;
            });
    
            //当父子任务都执行完毕后,显示结果。这句比较重要,为parent增加了回掉,对parent的结果parentTask.Result==results进行循环显示
            var cwt = parent.ContinueWith(parentTask => 
                                Array.ForEach(parentTask.Result, Console.WriteLine));
    
            // 开始父任务,子任务将会执行
            parent.Start();
    
            cwt.Wait(); // 测试等待回掉效果
        }
    }
    劳神费力的,点歌赞打赏打赏
  • 相关阅读:
    173. Binary Search Tree Iterator
    199. Binary Tree Right Side View
    230. Kth Smallest Element in a BST
    236. Lowest Common Ancestor of a Binary Tree
    337. House Robber III
    449. Serialize and Deserialize BST
    508. Most Frequent Subtree Sum
    513. Find Bottom Left Tree Value
    129. Sum Root to Leaf Numbers
    652. Find Duplicate Subtrees
  • 原文地址:https://www.cnblogs.com/zfcflower/p/2794021.html
Copyright © 2011-2022 走看看