剩女会被家人催,被邻居议论吗

小说:剩女会被家人催,被邻居议论吗作者:帝平顺更新时间:2019-03-23字数:23888

韩非马上写了一封回信过去,接受了张司令员的邀请,并且答应立即派出一批人员来江南支队,协助他们进行训练等事宜,指导可说不上,只能是协助,韩非知道,这些江南支队的老兵现在缺少的就是武器弹药,他们的单兵战斗力绝不比国民党军队的差的。

送给2015正在奋斗的你!

雷欧奈的身体完全就是随着音乐摇摆起来,身体还时不时和刘皓撞在一起,相互搭配起来,将她那性感火辣的身材展现得淋漓尽致,让周围的男人都双目火热的望着他,更是用嫉妒的目光望着刘皓。
张安邦又带着他们转了几个地方,这里虽然与外界隔离,但是生活却与外界差不多,或许是因为这里的大部分人都是从外面来的原因吧。

“雷神借法,诛邪!”剑尖所指之处,一道道天雷辐射过去将瑶池圣母的红色闪电全部抵消,旋转马叮当飞身而起,身如陀螺舞动着手中法剑,她简直就好像不是在战斗,而是在耍剑舞似的,曼妙无比。

  前面两篇回顾线程和线程池的使用方法,微软在.NET4.5推出了新的线程模型-Task。本篇将简单的介绍Task的使用方法。

Task与线程

  Task与线程或者说线程池关系紧密,可以说是基于线程池实现的,虽说任务最终还是要抛给线程去执行,但是Task仍然会比线程、线程池的开销要小,并且提供了可靠的API来控制线任务执行。

  使用Task来执行的任务最终会交给线程池来执行,若该任务需要长时间执行,可以将其标记为LongRunning,这是便会单独去请求创建线程来执行该任务。

Task

 创建

  Task的创建也存在两种方式,使用new或者使用静态工厂方式来创建:

        static void Main(string[] args)
        {

            Task t = new Task(Menthod1);
            t.Start();

            Task.Factory.StartNew(Menthod2);
            
            Console.WriteLine("主线程的ID:{0}", Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine("--------------------");
            Console.ReadLine();
        }

        static void Menthod1()
        {
            Thread.Sleep(2000);
            Console.WriteLine("线程1的ID:{0}", Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine("--------------------");
        }
        static void Menthod2()
        {
            Thread.Sleep(4000);
            Console.WriteLine("线程2的ID:{0}", Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine("--------------------");
        }

  上面说到使用Task执行任务最终还是需要线程池来执行,若不想让线程池来执行,可以添加LongRunning标志:

        Task t = new Task(Menthod1, TaskCreationOptions.LongRunning);
        t.Start();

        Task.Factory.StartNew(Menthod2, TaskCreationOptions.LongRunning);

   TaskCreationOptions还有很多枚举值,用来控制任务的更多属性。

 参数与返回值

  使用Task也可以传入参数(object类型)与返回值:

        static void Main(string[] args)
        {

            Task.Factory.StartNew(Menthod1, 233);
            //int result = Task.Factory.StartNew(new Func<object, int>(Menthod3), 233).Result;
            Task<int> t = Task.Factory.StartNew(new Func<object, int>(Menthod3), 233);
            int result = t.Result;

            Console.WriteLine("主线程的ID:{0}", Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine("result:{0}", result);
            Console.WriteLine("--------------------");
            Console.ReadLine();
        }

        static void Menthod1(object obj)
        {
            Thread.Sleep(2000);
            Console.WriteLine("线程1的ID:{0}", Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine("obj:{0}", obj);
            Console.WriteLine("--------------------");
        }
        static int Menthod3(object obj)
        {
            Thread.Sleep(6000);
            Console.WriteLine("线程3的ID:{0}", Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine("obj:{0}", obj);
            Console.WriteLine("--------------------");
            return obj;
        }

   这里为了获取返回值,阻塞了主线程,这里请注意一下。

 等待Task

  可以使用Task实例的Wait方法来实现等待任务结束,也可以向多线程一样,使用WaitAll和WaitAny一样来等待多个任务结束,不过操作更为简单:

        t.Wait();
        Task.WaitAll(t1, t2 ...);
        Task.WaitAny(t1, t2 ...);

 

 取消Task

  任务也是可以事先取消的,不过需要使用CancellationTokenSource:

        static void Main(string[] args)
        {
            Task.Factory.StartNew(Menthod1);

            CancellationTokenSource cancelTokenSource = new CancellationTokenSource();
            Task.Factory.StartNew(Menthod2, cancelTokenSource.Token);
            cancelTokenSource.Cancel();

            Console.WriteLine("主线程的ID:{0}", Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine("--------------------");
            Console.ReadLine();
        }

  上述代码就可以将线程2给取消掉,当然,Cancel方法可以自己找个合适的地方调用。

 

 继续Task

   在Task中,可以实现在一个任务结束后开启另一个新的任务:

        static void Main(string[] args)
        {
            Task t = Task.Factory.StartNew(Menthod1);
            t.ContinueWith(new Action<Task>(Menthod4));

            Console.WriteLine("主线程的ID:{0}", Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine("任务t的ID:{0}", t.Id);
            Console.WriteLine("--------------------");
            Console.ReadLine();
        }

        static void Menthod1()
        {
            Thread.Sleep(2000);
            Console.WriteLine("线程1的ID:{0}", Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine("--------------------");
        }
        static void Menthod4(Task t)
        {
            Console.WriteLine("线程4的ID:{0}", Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine("任务t的ID:{0}", t.Id);
            Console.WriteLine("--------------------");
        }

  这里因为使用了委托,也可以使用lambda表达式,更简单一些调用:

        Task t = Task.Factory.StartNew(Menthod1);
        t.ContinueWith(task =>
        {
            Console.WriteLine("线程4的ID:{0}", Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine("任务t的ID:{0}", task.Id);
            Console.WriteLine("--------------------");
        });

  

总结

  使用传统线程方式来进行多线程编程的时候,对线程的控制总是不到位,产生一些奇奇怪怪的问题;或是代码写得很杂乱;或是开发人员乱用线程,比方说无限制的创建线程、将线程池线程占满,等等。

  Task的出现,实现对传统线程操作的封装,提供可靠高效的API来控制线程,极大的方便多线程编程,所以可以用到Task的地方尽量使用Task;当然,这里仍会产生线程安全的问题,同样需要进行线程同步,与上一篇处理方式类似。

  Task的内容还有很多,更深层的运行原理、封装还等着我们去了解,现在只把我用到的东西分享出来,希望能帮助到需要的人。

  线程的学习就先告一段落了,敬请期待新的内容吧。

 

编辑:王宗纯

发布:2019-03-23 02:44:23

当前文章:http://www.cnsdbtzg.com/zfap0iznfj.html

妈妈要重视,宝宝打呼噜,不是睡得香! 一个没带手机的下午,我是这样度过的 24个细节深度解读《美人鱼》 终于找到适合自己的学习方法 孩子出生重要的前3年 孩子的好习惯不是靠培养出来的! 防雾霾12招!为了咱可以活久点,可得好好看看! 分手后,还会与前任做朋友吗?

40581 13732 64468 27786 18198 72524 61079 35569 59342 44380 42453 12087 66592 60255 31259 73525 91134 42669 28156 74723

我要说两句: (0人参与)

发布