zoukankan      html  css  js  c++  java
  • c# 多线程

    多线程

    .net 4.0 Task类的出现提高了线程的使用效率

    外部变量

            int i = 0;
            //100以内的随机数
            Random r = new Random(100);
            Task t = new Task(() =>
            {
                for (int v = 0; v < 100; v++)
                    //最大值50
                    i += r.Next(50);
            });
            t.Start();  //开始线程
            t.Wait();   //等待线程结束
            Console.WriteLine("这是执行Task1后等待完成:" + i.ToString());
    

    内部变量

            Random r = new Random(DateTime.Now.Second);
            //Task<T>直接返回结果
            //当调用Result属性时,会自动等待线程结束,等同调用了Wait()。
            Task<int> t = new Task<int>(() =>
            {
                int i = 0;
                for (int v = 0; v < 100; v++)
                    i += r.Next(100);
                return i;
            });
            t.Start();  //开始线程
            Console.WriteLine("这是执行Task1后等待完成:" + t.Result.ToString());
    

    ContinueWith

            Random r = new Random(DateTime.Now.Second);
            Task<int> t = new Task<int>(() =>
            {
                int i = 0;
                for (int v = 0; v < 100;v++ )
                    i += r.Next(100);
                return i;
            });
            t.ContinueWith((Task<int> task) =>
            {
                    Console.WriteLine("这是执行完毕Task1后继续调用Task2:" + task.Result.ToString());    
            });
            t.Start();
    

    ContinueWith链式写法

            Random r = new Random(DateTime.Now.Second);
            Task<int> t = new Task<int>(() =>
            {
                int i = 0;
                for (int v = 0; v < 100; v++)
                    i += r.Next(100);
                return i;
            });
            Task t2 = t.ContinueWith((Task<int> task) =>
            {
                Console.WriteLine(task.Result.ToString());
            });
            t2.ContinueWith(task =>
                {
                    Console.WriteLine("这是执行完毕Task1后继续调用Task2,Task2后调用Task。");
                });
            t.Start();
    

    Task中断

            CancellationTokenSource cts = new CancellationTokenSource();
            var ctoken = cts.Token;
            Task t1 = new Task(() =>
            {
                for (int v = 0; v < 10; v++)
                {
                    if(ctoken.IsCancellationRequested)
                    {
                        //第一种写法
                        //这个会抛出异常
                        ctoken.ThrowIfCancellationRequested();
    
                        //另一种写法
                        //这个不会返回异常,但是获取不到是否是中断还是执行完毕。
                        //return;
                    }
                    Thread.Sleep(1000);
                    Console.WriteLine(v);
                }
            },ctoken);
            t1.Start();
            Thread.Sleep(2000);
            cts.Cancel();
            try
            {
                t1.Wait();
            }
            catch
            {
                if (t1.IsCanceled)
                    Console.WriteLine("cancel");
            }
            cts.Dispose();
    
              中途取消Task执行,Token
             一是正常结束、二是产生例外、三是透过Cancel机制,这三种情况都会反映在Task.Status属性上
             值                                    说明
             Created                                    Task已经建立,但未呼叫Start。
             WaitingForActivation             Task已排入排程,但尚未执行(一般我们建立的Task不会有此状态,只有ContinueWith所产生的Task才会有此状态)。
             WaitingToRun                         Task已排入排程,等待执行中。
             Running                                   Task执行中。
             WaitingForChildrenToComplete    Task正等待子Task結束。
             RanToCompletion                  Task已经正常执行完毕。
             Canceled                                 Task已被取消。
             Faulted                                    Task执行中发生未预期例外。
    
             除了Status属性外,Task还提供了另外三个属性来判定Task状态。
             属性                     说明
             IsCompleted      Task已经正常执行完毕。
            IsFaulted            Task执行中法生未预期例外。
             IsCanceled         Task已被取消。
    

    StartNew

    创建一个新线程,并且直接运行,省略了start的过程

                Task<int> t1 = Task.Factory.StartNew<int>(() =>
                    {
                        int total = 0;
                        for (int i = 0; i < 10; i++)
                            total += i;
    
                        Console.WriteLine("线程运行");                    
                        Thread.Sleep(12000);
                        return total;
                    });
    
    

    ContinueWhenAny

    t1,t2中有任何一个task完成都会触发ContinueWhenAny线程,该线程只执行一次

                Task<int> t1 = Task.Factory.StartNew<int>(() =>
                    {
                        int total = 0;
                        for (int i = 0; i < 10; i++)
                            total += i;                    
                        Thread.Sleep(12000);
                        return total;
                    });
    
                Task<int> t2 = Task.Factory.StartNew<int>(() =>
                    {
                        int total = 0;
                        for (int i = 10; i < 20; i++)
                            total += i;
                        Thread.Sleep(10000);
                        return total;
                    });
                Task tfinal = Task.Factory.ContinueWhenAny<int>(
                    new Task<int>[] { t1, t2 }, (Task<int> task) =>
                        {
                            if (task.Status == TaskStatus.RanToCompletion)
                            {
                                Console.WriteLine(task.Result);
                            }
                        });
    

    ContinueWhenAll

    t1,t2全部执行完毕之后,会触发ContinueWhenAll线程,该线程只执行一次

                Task<int> t1 = Task.Factory.StartNew<int>(() =>
                    {
                        int total = 0;
                        for (int i = 0; i < 10; i++)
                            total += i;
                        Thread.Sleep(12000);
                        return total;
                    });
    
                Task<int> t2 = Task.Factory.StartNew<int>(() =>
                    {
                        int total = 0;
                        for (int i = 10; i < 20; i++)
                            total += i;
                        Thread.Sleep(10000);
                        return total;
                    });
                Task tfinal = Task.Factory.ContinueWhenAll(
                    new Task<int>[] { t1, t2 },(Task<int>[] taskCollection) =>
                        {
                            foreach (var task in taskCollection)
                            {
                                Console.WriteLine(task.Result);
                            }
                        });
    
  • 相关阅读:
    IntelliJ IDEA插件-常用插件
    Java代码规范和质量检查插件-Checkstyle(官方资源)
    Google代码风格配置文件(Java)(IDEA/Eclipse)
    Java中常量定义在interface和class的区别(转)
    Mac下安装Iterm2终端工具
    Ubuntu 16.04安装IntelliJ出品的数据库管理工具DataGrip
    Ubuntu 16.04安装JAD反编译工具(Java)
    Java中String字符串toString()、String.valueOf()、String强转、+ ""的区别
    微信开发(一)基于Wx-java的微信分享功能
    spring@value取不到值的几种情况
  • 原文地址:https://www.cnblogs.com/tangpeng97/p/13703829.html
Copyright © 2011-2022 走看看