zoukankan      html  css  js  c++  java
  • 任务

    1、创建任务的四种方式:
    第一种方式是实例化TaskFactory类,在其中把TaskMethod方法传递给StartNew方法,就会立即启动任务。

            var tf = new TaskFactory();
            var t1 = tf.StartNew(TaskMethod, "using a task factroy");
    

    第二种是使用Task的静态属性Factory来访问TaskFactory,以及调用StartNew()方法。

            var t2 = Task.Factory.StartNew(TaskMethod, "factroy via a task");
    

    第三种是使用Task类的构造函数,调用Start()方法来启动任务

            var t3 = new Task(TaskMethod, "using a task constructor and start");
            t3.Start();
    

    第四种调用Task的run方法,立即启动任务。传递Action类型的lambda表达式并在其实现中使用参数

           Task t4 = Task.Run(()=>TaskMethod("using the run method"));
    

    2、同步任务
    任务不一定要使用线程池中的线程,也可以使用其他线程。任务可以同步运行,以相同的线程为主调线程。这里TaskMethod方法首先在主线程上直接调用,然后在新的创建的Task上调用。下面的例子中:主线程是一个前台线程,没有任务ID也不是线程池中的线程。调用RunSynchronously方法时,会使用相同的线程作为主调线程,但是如果以前没有创建任务,就会创建一个任务。

       public static void RunSynchronousTask()
        {
            TaskMethod("just the main thread");
            var t1 = new Task(TaskMethod,"run sync");
            t1.RunSynchronously();
        }
    

    3、使用单独线程的任务
    如果任务的代码应该长时间运行,就应该使用TaskCreationOptions.LongRunning告诉任务调度创建一个新的线程,而不是使用线程池中的线程。此时,线程可以不由线程池管理。当线程来自线程池时,任务调度器可以决定等待已经运行的任务完成,然后使用这个线程,而不是在线程池中建一个新线程。对于长时间运行的线程,任务调度器会立即知道等待他们完成不是明智的做法。

       public static void LongRunningTask()
        {
            var t1 = new Task(TaskMethod,"Long running",TaskCreationOptions.LongRunning);
            t1.Start();
        }
    

    4、取消架构
    取消架构基于协作行为,它不是强制性的。长时间运行的任务会检查它是否被取消,并返回控制权。支持取消的方法接受一个CancellationToken参数。这个类定义了IsCancellationRequested属性,其中长时间运行的操作可以检查它是否终止。长时间运行的操作检查取消的其他方式有:取消标记时,使用标记的WaitHandle属性,或者使用Registed()方法。Registed()方法接受Action和ICancelableOperation类型的参数。Action委托的方法在取消标记时调用。
    4.1、 Parallel.For()方法的取消

          var cts = new CancellationTokenSource();
            cts.Token.Register(() => Console.WriteLine("**********token canceled***********"));
            cts.CancelAfter(500);
    
            try
            {
                ParallelLoopResult result = Parallel.For(0, 100, new
                    ParallelOptions()
                {
                    CancellationToken = cts.Token,
                },
                x=> {
                    Console.WriteLine("loop {0} started",x);
                    int sum = 0;
                    for (int i = 0; i < 100; i++)
                    {
                        Thread.Sleep(2);
                        sum += i;
                    }
                    Console.WriteLine("loop {0} finished",x);
                });
            }
            catch(OperationCanceledException ex)
            {
                Console.WriteLine(ex.Message);
            }
    

    4.2任务的取消
    同样的操作也可用于任务。运行应用程序,可以看到任务启动了,运行几个循环,并获得了取消请求。之后取消任务,并抛出TaskCanceledException异常,他是从方法调用ThrowIfCancellationRequested()中启动的,调用者等待任务时,会捕获AggregateException异常,它包含内部异常TaskCanceledException。

        var cts = new CancellationTokenSource();
            cts.Token.Register(() => Console.WriteLine("**********token canceled***********"));
            cts.CancelAfter(500);
    
            Task t1 = Task.Run(()=> {
                Console.WriteLine("in task");
                for (int i = 0; i < 20; i++)
                {
                    Thread.Sleep(100);
                    CancellationToken token = cts.Token;
                    if(token.IsCancellationRequested)
                    {
                        Console.WriteLine("cancelling was requested,cancelling from within the task");
                        token.ThrowIfCancellationRequested();
                        break;
                    }
                    Console.WriteLine("in loop");
                }
                Console.WriteLine( "task finished without cancellation");
            },cts.Token);
    
            try
            {
                t1.Wait();
            }
            catch(AggregateException ex)
            {
                Console.WriteLine( "execption:{0},{1}",ex.GetType().Name,ex.Message);
                foreach (var item in ex.InnerExceptions)
                {
                    Console.WriteLine( "inner exception:{0},{1} ",ex.InnerException.GetType().Name,ex.InnerException.Message);
                }
            }
    

  • 相关阅读:
    文件操作
    POJO对象建立规则
    第三章 Java 的基本程序设计结构
    第一章 Java程序设计概述
    Dao层设计
    业务功能迭代开发过程
    mysql 修改语法格式
    自定义 Java 异常 (Exception)
    接口开发注意事项-个人总结
    intelliJ IDEA springMVC 搭建配置
  • 原文地址:https://www.cnblogs.com/caozhengze/p/10046631.html
Copyright © 2011-2022 走看看