await与async的正确打开方式,架构的血液

2019-11-18 13:30 来源:未知

关于开发者的技术水平到底该如何定义,到底一个人的技术水平应该定位在高、中、低的标准是什么呢?很多人觉得这是一个仁者见仁的问题,有人觉得根据公司的那个员工等级判断。答案是肯定不是,从纯开发技术的角度来分析。很多人觉得自己一门语言精通了就去学其他语言了,美其名曰集大成者,这样的工作十几年却是初级水平的技术人员也不少。

本篇文章主要介绍委托的应用。

C#5.0推出了新语法,await与async,但相信大家还是很少使用它们。关于await与async有很多文章讲解,但有没有这样一种感觉,你看完后,总感觉这东西很不错,但用的时候,总是想不起来,或者不知道该怎么用。

下面我来讲讲我的认知,C#这门技术到底学到什么程度可以进入到什么级别。

委托是大家最常见的语法了,但会用与精通之间的差别是巨大的。

为什么呢?我觉得大家的await与async的打开方式不正确。

我常说C#的入门技术是委托、事件、消息。只有当你可以纯熟运用这三个技能的时候,才刚刚入门,此时C#的大门才算正式为你打开。很多人在学了一些语法编写一些项目后就觉得C#精通了,其实你们还没入门呢(对日开发的居多)

一个程序员如果不能精通委托,那么,他永远无法成为高级程序员。

 正确的打开方式

下面上一个图片,大家来看看自己的定位,当然是纯技术角度,其实,有些时候一个软件架构,用初级软件工程师也是可以架构的。

所以,让我们把委托刻到血液里吧。

 

  图片 1

这样,你才能称为[Developer]。

首先看下使用约束。

 

委托的定义

1、await 只能在标记了async的函数内使用。

1,        comom language runtime :初级人员无视他,中级人员起码要知道他,高级人员多数要会使用其中一些应用比如security,架构师要理解原理。

什么是委托?

2、await 等待的函数必须标记async。

2,        .netframework :这里有许多框架,会的越多越好。

委托实际上是一种类型,是一种引用类型。

有没有感觉这是个循环?没错,这就是个循环。这也就是为什么大家不怎么用他们的原因。这个循环很讨厌,那么怎么破除这个循环呢?

3,        Base class library :这里都是基本语法你会了多少呢,想成为高手一定要全部学会,一个都不能丢。

微软用delegate关键字来声明委托,delegate与int,string,double等关键字一样。都是声明用的。

【很简单,await等待的是线程,不是函数。】

4,        Runtime infrastructure library:这里内容初级开发者不用了解,进入中级就要开始一点点吸收了,想到高级要全部消化,是全部哦。

下面先看下声明代码,这里声明了两个委托。

不理解吗?没关系,接着看下去。

5,        Framework calss library:这里都是基本应用,初级程序员肯能都会接触一些,中级就会了解和运用一些,高级就要全部会用。

public delegate void TestDelegate(string message);
public delegate int TestDelegate(MyType m, long num);

下面从头来讲解,首先看这么一组对比

6,        Core concepts:这里的内容同上。

delegate既然是关键字,和int,string一样,那么,为什么delegate后又跟了一个void或者int呢?

public static int NoAsyncTest()
{
   return 1;
}
public static async Task<int> AsyncTest()
{ 
  return 1;
}

7,        Core features,core objects,CLI language,DLR略过。。。

如果他们是同等地位的关键字,为什么可以一起使用呢?

 async Task<int>等于int

8,        Desktop:CUI了解就行,GUI要深入了解,另外这里的涉及到了XAML语言,这个要学会。

很简单,我们把delegate后面的 【void TestDelegate(string message)】理解为一个变量,是不是就清晰明了了一些。

这意味着我们在正常调用这两个函数时,他们是等效的。那么用async Task<int>来修饰int目的是什么呢?

9,        Web:这里涉及的框架sharpoint如果工作没涉及不去了解也是可以的,但asp.net是必会的,其中的MVC就算工作没应用也要学会。Asp.net runtime是进阶高手的一个路障,了解的越多越好。Silverlight的话,会xaml基本就能用,如果工作需要精通。

我们把delegate关键字理解为,是用来专门来定义这种复杂的变量的。而这种复杂的变量可以包含一个返回值和任意数目任意类型的传入参数。

目的是为了让这个方法这样被调用 await AsyncTest(),但直接这样调用,并不会开启线程,那这样费劲的修饰是不是就没什么意义了呢。

10,     SOA:这也是个必会的东西,而且至少要精一个。

有没有感觉,这个复杂的变量特别像一个函数的定义。

当然不是,那什么时候会让 await AsyncTest()有意义呢?

11,     Open web interface for .net:要了解,会使用,如果工作需要,要精通。

没错,官方定义,委托类型的声明与方法签名相似。所以,这个复杂变量,的确,书写的方式就是与函数一样。

我们接着往下看,修改AsyncTest如下。然后,此时再调用await AsyncTest(),你会神奇的发现,依然没有卵用。。。

12,     SDK:要了解,会基本使用。

那么,为什么这个声明方式如此怪异呢,是因为,我们用delegate定义的变量,只能用函数赋值。赋值方式如下所示:

Excute方法正常执行,而AsyncTest内运行的线程,自己执行自己的。

13,     Development:这个基本没有人能全会,但工具这个要熟练使用,毕竟工具会的越多越好,但不是技术加分。

public delegate void TestDelegate(string message);
public delegate long TestDelegate2(int m, long num);
public static void Excute()
{
    TestDelegate2 td = Double; 
} 
static long Double(int m, long num)
{
    return m * num;
}
public static async void Excute()
 {
       Console.WriteLine(Thread.CurrentThread.GetHashCode() + " 开始 Excute " + DateTime.Now);
       await AsyncTest();
       Console.WriteLine(Thread.CurrentThread.GetHashCode() + " 结束 Excute " + DateTime.Now);
 }

 public static async Task<int> AsyncTest()
 {
        Task.Run(() =>
            {
                Console.WriteLine(Thread.CurrentThread.GetHashCode() + " Run1 " + DateTime.Now);
                Thread.Sleep(1000);
            });
            return 1;
 }

14,     Platforms:这个基本很难有人全精,但多少要了解,工作用过的要精通。

委托的基本应用

图片 2

15,     Productivity:起码nuget要会用。

学会了赋值以后,我开始使用委托。

别着急,我们稍作调整,在线程后面增加.GetAwaiter().GetResult()。这句话是干什么用的呢?是用来获取线程返回值的。

16,     Build:高级人员要了解原理。

委托的使用方式如下:

这个逻辑是这样的,如果想要获取线程返回结果,就自然要等待线程结束。

17,     Testing:至少要会使用1个,其他的要了解。

string result = td(51, 8);
Console.WriteLine(result);

运行一下,我们将看下面的结果。

18,     Deploy/publish:这个基本都百度的出用法,了解就可以,起码知道有这个东西,需要的时候可以百度。

这里我们会发现,委托的使用方式与函数调用一样。

public static async Task<int> AsyncTest()
        {
            Task.Run(() =>
            {
                Console.WriteLine(Thread.CurrentThread.GetHashCode() + " Run1 " + DateTime.Now);
                Thread.Sleep(1000);
            }).GetAwaiter().GetResult();
            return 1;
        }

19,     Framework tool:这里有些是必会的,有些会用就行,但最好全部了解,需要的时候学习用法。

没错,它们的确是一样的。因为委托是用函数来赋值的,所以调用方式一样也并不奇怪,不是吗。

图片 3 

20,     Data:这里内容作为高级人员是必会的,如果其中的orm可以用EF作为跳板深入研究(这里的水很深)。

换一种说法,就是委托封装了一个函数。

但是,好像await AsyncTest();还是没启作用。没错,事实就是,他真的不会起作用。。。

21,     Conponents:中级以后难免要接触这些,了解的越多进步的越多。

如果委托是封装的函数,并且它又是引用类型。那么委托第一种常规的应用就浮现出来了。

那么怎么才能让他起作用呢?

22,     Concept:这是图片里没有的,中级以后就会接触的,像什么IOC,AOP,MVC,MVVM,DDD等等,在学习这些的过程中可以逐渐向架构师前进,其实这些概念学会了之后会发现,概念只是装逼用的。在概念里分为基本概念和高级概念,像IOC,AOP就是基本概念,这些东西在编码时你已经应用过了,而且有一些现成的开源代码,而且原理很简单,学会后可以用具体语言来把你编码的方式表达出来,不去了解也无妨,但知道的多了,方便忽悠;而DDD就是高级概念,光百度是学不会的,一定要应用过才能了解,但DDD这样的高级概念很复杂,非技术人员很难理解,技术人员也未必有那么好的口才讲解,而IOC,AOP这类的简单概念很容易理解,基本上口才笨拙的开发人员也能讲的很溜,很适合给领导很讲解。所以在领导看来,会基础概念和会高级概念都是一样一样一样地。 

那就是——引用类型的函数。

首先,我们定义一个普通函数,他的返回值是一个Task,然后我们得到Task后,运行它,再用await等待这个Task。

看到这里是不是那些以为C#很简单的同学就很吃惊啦啊,那些自以为自己是大神的是不是发现,原来自己不过才是刚入门的小菜鸟啦,那些以为自己C#精通的外包达人们,是不是打开图片后一脸陌生的感觉呀。其实,C#并不比其他语言简单,水深的狠,哪那么容易精通。

如果函数是引用类型,那么这个函数只要没被内存回收,就可以被调用。如果是public函数或者是public static函数,那么它能跨越的东西就更多了。

于是我们就得到这样的结果。

这些还只是C#,作为一个程序员,还要有其他必备的知识,比如HTML和CSS你得会,JS你得会,别说你知道标签是什么意思就说自己会了,起码DIV+CSS切图玩的起来才算会。数据库你得会,数据库水很深,别轻易说自己有初级DBA的水平,那些传说中每天备份表数据的初级DBA可是连入门都没有呢,不要和他们比;作为高级开发人员,起码存储过程要信手拈来把,起码要有解决过大数据死锁的经验吧。如果业余爱好再丰富一点的人,PS基本使用也要会把,falsh也要了解吧,3Dmax是不是也可以玩玩啊,程序员也要有美感嘛。此外,程序员要会写文档,解决方案可是基本技能,高级点的概要设计也是文档嘛。另外高级程序员难免还得写点ppt吧。

比如可以跨类调用,跨程序集调用等等。而这种用法,就是委托的基本应用。

 public static async void Excute()
        {
            Console.WriteLine(Thread.CurrentThread.GetHashCode() + " 开始 Excute " + DateTime.Now);
            var waitTask = AsyncTestRun();
            waitTask.Start();
            int i = await waitTask;
            Console.WriteLine(Thread.CurrentThread.GetHashCode() + " i " + i);
            Console.WriteLine(Thread.CurrentThread.GetHashCode() + " 结束 Excute " + DateTime.Now);
        }
        public static Task<int> AsyncTestRun()
        {
            Task<int> t = new Task<int>(() => {
                Console.WriteLine(Thread.CurrentThread.GetHashCode() + " Run1 " + DateTime.Now);
                Thread.Sleep(1000);
                return 100;
            });
            return t;
        }

除了这些,还有一些要了解的东西,比如操作系统呀,硬件呀,软件工具等等,因为不一定什么时候你面对着一些性能bug,就需要他们的知识才能解决,或者解释。

匿名委托的应用

图片 4  

再更上一层楼,要接触一些开源代码啦,现在Xamarin都开源了,你有去了解吗?很多开源代码都很厉害的,不要对我说在CSDN下载了一些开源代码啊。。。

匿名委托的官方介绍:在 2.0 之前的 C# 版本中,声明委托的唯一方式是使用命名方法。 C# 2.0 引入匿名方法,在 C# 3.0 及更高版本中,Lambda 表达式取代匿名方法作为编写内联代码的首选方式。

如图,这样写await AsyncTest();就起作用了。

【PS:如果有需要购买Xamarin安卓框架的可以联系我,分为原始框架和web嵌入框架两种,后者采用angularjs+web api技术,Web页面端实现MVVM :)】

看不懂没关系,我们直接来学习使用。代码如下:

所以,还是那句话,await等待的是线程,不是函数。

 以上全部是纯技术分析,当然不是全部,如有遗漏欢迎大家补充。

delegate string anonymousDelegate(int m, long num);
public static void Excute()
{
    anonymousDelegate ad = delegate (int m, long num) { return m.ToString() + num.ToString(); };//2.0时代的匿名委托
    anonymousDelegate ad2 = (m, num) => { return m.ToString() + num.ToString(); };//3.0以后匿名委托 
}

但在图里,我们发现很奇怪的一点,结束Excute也是线程3,而不是线程1。也就是说,Await会对线程进行优化。

TAG标签:
版权声明:本文由澳门金莎娱乐网站发布于澳门金莎唯一指定官网,转载请注明出处:await与async的正确打开方式,架构的血液