zoukankan      html  css  js  c++  java
  • c#异步编程一

    1.什么是异步

    程序启动时,系统会在内存中创建一个新的进程,进程是构成运行程序的资源合集,

    在进程内部,系统创建了一个称为线程的内核对象,它代表了真正执行的程序,

    关于线程:

    默认情况下,一个进程只包含一个线程,从程序开始一直执行到结束,

    线程可以派生其他线程,因此在任意时刻,一个进程都可能包含不同状态的多个线程,来执行程序的不同部分,

    系统为处理器执行所规划的单元是线程,不是进程,

    不使用异步示例:

     class MyDownload
        {
            Stopwatch sw = new Stopwatch();
    
            public void DoRun()
            {
                const int LargeNumber = 6000000;
    
                sw.Start();
    
                int t1 = CountCharacters(1, "http://www.miscrosoft.com");
                int t2 = CountCharacters(2, "http://www.illustratedcsharp.com");
    
                CountToALargeNumber(1, LargeNumber);
                CountToALargeNumber(2, LargeNumber);
                CountToALargeNumber(3, LargeNumber);
                CountToALargeNumber(4, LargeNumber);
    
                Console.WriteLine("Chars in http://www.miscrosoft.com  {0}", t1);
                Console.WriteLine("Chars in http://www.illustratedcsharp.com {0}", t2);
            }
    
            private int CountCharacters(int id, string uristring)
            {
                WebClient wc1 = new WebClient();
                Console.WriteLine("Starting call {0}  :  {1, 4:N0} ms", id, sw.Elapsed.TotalMilliseconds);
                string result = wc1.DownloadString(new Uri(uristring));
                Console.WriteLine("  Call {0} completed  :  {1, 4:N0} ms", id, sw.Elapsed.TotalMilliseconds);
                return result.Length;
            }
    
            public void CountToALargeNumber(int id, int value)
            {
                for (long i = 0; i < value; i++) ;
                Console.WriteLine("  End counting {0}  :  {1, 4:N0} ms", id, sw.Elapsed.TotalMilliseconds);
            }
    
        }
     class Program
        {
            static void Main(string[] args)
            {
                MyDownload md = new MyDownload();
                md.DoRun();
                Console.ReadKey();
            }
        }

    如果我们能初始化两个CountCharacter调用,无需等待结果,而是直接执行4个CountToALargeNumber调用,然后在两个CountCharacter方法调用结束后在获取结果,就可以显著的提升性能,即async/await,

    class MyDownload
        {
            Stopwatch sw = new Stopwatch();
    
            public void DoRun()
            {
                const int LargeNumber = 6000000;
    
                sw.Start();
    
                Task<int> t1 = CountCharactersAsync(1, "http://www.miscrosoft.com");
                Task<int> t2 = CountCharactersAsync(2, "http://www.illustratedcsharp.com");
    
                CountToALargeNumber(1, LargeNumber);
                CountToALargeNumber(2, LargeNumber);
                CountToALargeNumber(3, LargeNumber);
                CountToALargeNumber(4, LargeNumber);
    
                Console.WriteLine("Chars in http://www.miscrosoft.com  {0}", t1.Result);
                Console.WriteLine("Chars in http://www.illustratedcsharp.com {0}", t2.Result);
            }
    
            private async Task<int> CountCharactersAsync(int id, string uristring)
            {
                WebClient wc1 = new WebClient();
                Console.WriteLine("Starting call {0}  :  {1, 4:N0} ms", id, sw.Elapsed.TotalMilliseconds);
                string result = await wc1.DownloadStringTaskAsync(new Uri(uristring));
                Console.WriteLine("  Call {0} completed  :  {1, 4:N0} ms", id, sw.Elapsed.TotalMilliseconds);
                return result.Length;
            }
    
            public void CountToALargeNumber(int id, int value)
            {
                for (long i = 0; i < value; i++) ;
                Console.WriteLine("  End counting {0}  :  {1, 4:N0} ms", id, sw.Elapsed.TotalMilliseconds);
            }
    
        }
     class Program
        {
            static void Main(string[] args)
            {
                MyDownload md = new MyDownload();
                md.DoRun();
                Console.ReadKey();
            }
        }

    这些线程都是在主线程中完成的,我们没有创建任何额外的线程,

    2.asyncawait结构

    如果一个程序调用某个方法,等待其执行所有处理后才继续执行,这样的方法为同步方法,

    异步方法为处理完成之前就返回到调用方法,

    c#的async/await特性可以创建并使用异步方法,该特性由三个部分组成,

    调用方法:该方法调用异步方法,然后在异步方法执行其任务的时候继续执行,

    异步方法:该方法执行异步工作,然后立即返回到调用方法

    await表达式:用于异步方法内部,指明需要异步执行的任务,一个异步方法可以包含任意多个await表达式,如果一个不包含编译器会发出警告,

    调用方法如下:

     class Program
        {
            static void Main(string[] args)
            {
                Task<int> value = DoAsyncStuff.CalculateSumAsync(5, 6); // 调用方法
                Console.WriteLine("value:{0}", value.Result);
                Console.ReadKey();
            }
        }

    异步方法如下:

     static class DoAsyncStuff
        {
            public static async Task<int> CalculateSumAsync(int n1, int n2)
            {
                int sum = await Task.Run(() => GetSum(n1, n2)); // 异步方法 await表达式
                return sum;
            }
    
            private static int GetSum(int n1, int n2)
            {
                return n1 + n2;
            }
        }

    3.什么是异步方法

    语法上,异步方法具有如下特点:
    方法头包含async方法修饰符,
    包含一个或多个await表达式,
    必须具备以下三种返回类型:Task<T>,Task,void,
    异步方法的参数可以为任意类型的任意数量,但不能为out和ref参数,
    按照约定,异步方法的名称应该以Async为后缀,
    除了方法以外,lambda表达式和匿名方法也可以作为异步对象,

    使用返回Task<int>对象的异步方法

    class Program
        {
            static void Main(string[] args)
            {
                Task<int> value = DoAsyncStuff.CalculateSumAsync(5, 6);
                Console.WriteLine("value:{0}", value.Result);
                Console.ReadKey();
            }
        }
    
        static class DoAsyncStuff
        {
            public static async Task<int> CalculateSumAsync(int n1, int n2)
            {
                int sum = await Task.Run(() => GetSum(n1, n2));
                return sum;
            }
    
            private static int GetSum(int n1, int n2)
            {
                return n1 + n2;
            }
        }

    使用返回Task对象的异步方法

     class Program
        {
            static void Main(string[] args)
            {
                Task value = DoAsyncStuff.CalculateSumAsync(5, 6);
                value.Wait();
                Console.WriteLine("Async stuff is done");
                Console.ReadKey();
            }
        }
    
        static class DoAsyncStuff
        {
            public static async Task CalculateSumAsync(int n1, int n2)
            {
                int sum = await Task.Run(() => GetSum(n1, n2));
                Console.WriteLine("sum:{0}", sum);
            }
    
            private static int GetSum(int n1, int n2)
            {
                return n1 + n2;
            }
        }

    使用“调用并忘记”的异步方法

     class Program
        {
            static void Main(string[] args)
            {
                DoAsyncStuff.CalculateSumAsync(5, 6);
                Thread.Sleep(200);
                Console.WriteLine("Program Exiting");
                Console.ReadKey();
            }
        }
    
        static class DoAsyncStuff
        {
            public static async void CalculateSumAsync(int n1, int n2)
            {
                int sum = await Task.Run(() => GetSum(n1, n2));
                Console.WriteLine("sum:{0}", sum);
            }
    
            private static int GetSum(int n1, int n2)
            {
                return n1 + n2;
            }
        }

    qq

  • 相关阅读:
    pip2 pip3
    linux 下加载移动硬盘
    linux 下使用 Synergy
    openSUSE 下安装 OpenCV
    PCA and ZAC Whitening
    openSUSE 安装 Torch
    [转] Python xrange与range的区别
    Linux下安装 mxnet
    Caffe hdf5 layer data 大于2G 的导入
    [CVPR2017] Visual Translation Embedding Network for Visual Relation Detection 论文笔记
  • 原文地址:https://www.cnblogs.com/huangxuQaQ/p/10861937.html
Copyright © 2011-2022 走看看