C#中的异步多线程2 async

同步:如果一个程序调用了某个方法,等待其执行所有处理后才继续执行下一步,就被称为同步。

异步:异步方法在处理完成之前就会返回到调用方法,async/await特性可以创建并调用异步方法。

async/await特性由3个部分组成:

1、调用方法:该方法调用异步方法,然后在异步方法(可能在相同线程,也可能在不同线程)执行其任务的时候继续执行。

static void Main()
{
   ...
   Task<int> value=DoAsyncStuff.CalculateSumAsync(5,6);
   ...
}

 

2、异步方法(async):该方法异步执行其工作,然后立即返回到调用方法。

public static async Task<int> CalculateSumAsync(int i1,int i2)
{
    int sum=await TaskEx.Run(()=>GetSum(i1,i2));
    return sum;
}

 

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

 

一、什么是异步方法

       如之前示例:

        public void DoRun()
        {
            const int LargeNumber = 600000;
            sw.Start();
            Task<int> t1 = CountCharactersAsync(1, "https://www.baidu.com");
            Task<int> t2 = CountCharactersAsync(2, "http://www.sougou.com");
            CountToALargeNumber(1, LargeNumber);
            CountToALargeNumber(2, LargeNumber);
            CountToALargeNumber(3, LargeNumber);
            CountToALargeNumber(4, LargeNumber);
            Console.WriteLine("Chars in Baidu:{0}", t1.Result);
            Console.WriteLine("Chars in Sougou:{0}", t2.Result);
        }

       CountCharactersAsync在完成其工作之前,就会返回到DoRun()方法,然后在DoRun()继续执行的时候继续完成CountCharactersAsync本身的工作。

       异步方法包含以下特点:

       1、方法头包含async修饰符。

       2、包含一个或多个await表达式,表示可以异步完成的工作。

       3、必须具备以下三种返回类型之一:void,Task,Task<T>,Task和Task<T>的返回对象表示将在未来完成的工作,调用方法和异步方法可以继续执行。

       4、异步方法的参数可以为任意类型任意数量,但不能为out或ref参数。

     (方法参数中如果引入了out关键字,该参数修饰的变量若在方法中被修改,会修改至外部定义,而不只是局限于方法体,但注意如果一个方法要使用带有out关键字的参数,那么要有不带out关键字的参数来操作赋值;ref关键字则为传引用,原本值类型的实参可能会在方法中被修改,但其本身不会影响到方法外部,方法中的实参只是一个副本,而如果使用了ref关键字修饰,则变为传引用,方法内的修改会直接影响到外部。还有一个in关键字,过程不会改写in的内容。)

      5、异步方法应当以Async为后缀。

      6、除了方法以外,lambda表达式和匿名方法也可以作为异步对象。

async Task<int> CountCharactersAsync(int id,string site)
{
   Console.WriteLine("Starting CountCharacters");
   WebClient wc=new WebClient();
   string result=await wc.DownloadStringTaskAsync(new Uri(site));//await表达式
   return result.Length;//返回语句
}

      A、async关键字

      异步方法在方法头中必须包含async关键字,且必须在返回类型之前。async修饰符只是标识该方法包含一个或多个await表达式,但async本身并不能创建任何异步操作。

      async关键字是一个上下文关键字,也就是说除了可以作为方法修饰符(或lambda、匿名方法修饰符)之外,还可以作为标识符。

      B、返回类型

      返回类型必须是以下三种类型之一:

      1、Task<T>:如果调用方法要从调用中获取一个T类型的值,异步方法的返回类型就必须是Task<T>。调用方法将通过读取Task的Result属性来获取这个T类型的值。

      

Task<T> value=DoStuff.CalculateSumAsync(5,6);
...
Console.WriteLine($"{value.Result}");

      2、Task:如果调用方法不需要从异步方法中返回某个值,但需要检查异步方法的状态,那么异步方法可以返回一个Task类型的对象。这时,即使异步方法中出现了return语句,也不会返回任何东西。

Task someTask=DoStuff.CalculateSumAsync(5,6);
...
someTask.Wait()

    3、void:如果调用方法仅仅想执行异步方法,而不需要和它进行任何进一步的交互时(调用并忘记),异步方法可以返回void类型,这时,即使异步方法中出现了return语句,也不会返回任何东西。

posted @ 2020-05-22 16:39  NicolasLiaoRan  阅读(247)  评论(0编辑  收藏  举报