任务

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);
            }
        }

posted @   泽哥的学习笔记  阅读(159)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示