C# 并行和多线程2

  1. 任务是架构在线程之上的,也就是说任务最终还是要抛给线程去执行。
  2. 任务跟线程不是一对一的关系,比如开10个任务并不是说会开10个线程,这一点任务有点类似线程池,但是任务相比线程池有很小 的开销和精确的控制。

一:Task

1. 最简单的使用

  开启task有两种方式:

<1> 实例化Task

    //第一种方式开启
         var task1 = new Task(() =>
         {
             Run1();
         });

 

<2>从工厂中创建

   var task2 = Task.Factory.StartNew(() =>
             {
                 Run2();
             });

2. 取消任务

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

 class Program
    {
        static void Main(string[] args)
        {
            CancellationTokenSource cts = new CancellationTokenSource();
            CancellationToken ct = cts.Token;

            Task task1 = new Task(() => { Run1(ct); }, ct);

            Task task2 = new Task(Run2);

            try
            {
                task1.Start();
                task2.Start();

                Thread.Sleep(1000);

                cts.Cancel();
                Task.WaitAll(task1, task2);
            }

            catch (AggregateException ex)
            {
                foreach(var e in ex.InnerExceptions)
                {
                    Console.WriteLine("\nhi,我是OperationCanceledException:{0}\n", e.Message);
                }
                Console.WriteLine("task1是不是被取消了? {0}", task1.IsCanceled);
                Console.WriteLine("task2是不是被取消了? {0}", task2.IsCanceled);
            }
            Console.Read();

        }

        private static void Run1(CancellationToken ct)
        {
            ct.ThrowIfCancellationRequested();
            Console.WriteLine("我是任务1");
            Thread.Sleep(2000);

            ct.ThrowIfCancellationRequested();
            Console.WriteLine("我是任务1的第二部分信息");
        }

        private static void Run2()
        {
            Console.WriteLine("我是任务2");
        }
    }

①:Run1中的Console.WriteLine("我是任务1的第二部分信息"); 没有被执行。

②:Console.WriteLine("task1是不是被取消了? {0}", task1.IsCanceled); 状态为True。

3. 获取任务的返回值

 

       static void Main(string[] args)
        {
            var t1 = Task.Factory.StartNew<List<string>>(() => { return Run1(); });
            t1.Wait();

            var t2 = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("t1集合中返回的个数:" + string.Join(",", t1.Result));
            });
            Console.Read();
        }

        private static List<string> Run1()
        {
            return new List<string> { "1", "4", "8" };
        }
    

<2>采用ContinueWith方法

        static void Main(string[] args)
        {
            var t1 = Task.Factory.StartNew<List<string>>(() => { return Run1(); });
            t1.Wait();

            var t2 = t1.ContinueWith((i) =>
            {
                Console.WriteLine("t1集合中返回的个数:" + string.Join(",", i.Result));
            });
            Console.Read();
        }

        private static List<string> Run1()
        {
            return new List<string> { "1", "4", "8" };
        }

4:ContinueWith结合WaitAll

        static void Main(string[] args)
        {
            ConcurrentStack<int> stack = new ConcurrentStack<int>();
            //t1先串行
            var t1 = Task.Factory.StartNew(() =>
            {
                stack.Push(1);
                stack.Push(2);
            });
            //t2,t3并行执行
            var t2 = t1.ContinueWith(t =>
            {
                int result;

                stack.TryPop(out result);
            });
            //t2,t3并行执行
            var t3 = t1.ContinueWith(t =>
            {
                int result;

                stack.TryPop(out result);
            });
            //等待t2和t3执行完
            Task.WaitAll(t2, t3);

            //t4先串行
            var t4 = Task.Factory.StartNew(() =>
            {
                stack.Push(1);
                stack.Push(2);
            });
            //t5,t6并行执行
            var t5 = t4.ContinueWith(t =>
            {
                int result;

                stack.TryPop(out result);
            });
            //t5,t6并行执行
            var t6 = t4.ContinueWith(t =>
            {
                int result;
                //只弹出,不移除
                stack.TryPeek(out result);
            });
            //临界区:等待t5,t6执行完
            Task.WaitAll(t5, t6);

            var t7 = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("当前集合元素个数:" + stack.Count);
                
            });

            Console.Read();
        }

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值