原文:https://blogs.msdn.microsoft.com/mazhou/2017/05/30/c-7-series-part-2-async-main/

你大概知道,C#语言可以构建两种程序。一种是带有入口点(entrypoint)的程序,这样操作系统就可以加载程序并从入口点执行;另一个是没有入口点的程序。操作系统不能直接执行程序,程序可以被其他有入口点的程序引用,这样就可以执行其中的代码。

必须有入口点的应用程序类型有:Windows Forms应用程序、UWP应用程序、控制台应用程序、WPF应用程序、ASP.NET和ASP.NET Core应用程序和Xamarian App。

不需要入口点的应用程序类型有:类库(/t:lib)、模块(/t:module)。

Main方法

像其他语言一样,C#程序从Main方法开始。有四个重载被认为是Main方法的有效签名。

public static void Main();
public static int Main();
public static void Main(string[] args);
public static int Main(string[] args);

C#的入口点方法必须是静态的,方法名必须是Main,这个方法的返回类型可以是void或者int,它可以有一个字符串数组的参数,包含任何命令行参数。

如果入口点方法返回一个int值,那么操作系统或使用此入口点启动程序的宿主进程可以评估这个返回值,这在本机环境(译注:与.NET的托管环境相对应)中广泛使用(比如表示外部应用程序的成功启动)。

异步的Main方法

C#在5.0版本(.NET Framework 4.5)中引入了异步/等待模式,使得异步操作的流程易于读懂。许多现有的,为那些异步操作(又名异步编程模型)设计的语言结构可以使用新的async/await关键字。今天,社区开发的许多类库只提供了异步版本的操作。(例如,System.Net.HttpClient, Microsoft.Azure.EventHub.Core.)

正如我在前面所提到的,如果你想在Main方法中等待异步操作,你需要应用一些变通方法,因为下面的Main方法定义是无效的(译注:在C#7.1之前的版本):

public static async Task Main(string[] args)
{
await BuildWebHost(args).RunAsync();
}

变通的办法是使用同步等待操作。

public static void Main(string[] args)
{
BuildWebHost(args).RunAsync().GetAwaiter().GetResult();
}

或者调用定义在Task的Wait()方法:

public static void Main(string[] args)
{
BuildWebHost(args).RunAsync().Wait();
}

在C# 7.1中,C#扩展了Main方法的有效签名,允许这些Main法的异步重载有效。

public static void Main();
public static int Main();
public static void Main(string[] args);
public static int Main(string[] args);
public static Task Main();
public static Task<int> Main();
public static Task Main(string[] args);
public static Task<int> Main(string[] args);

类Task的返回类型允许在Main方法使用async修饰符来实现await关键字。

结论

异步的Main方法使得入口点方法中的异步操作更容易使用,而不需要像在其他异步方法中运行那样使用任何变通方法。在代码编译的时候,任何异步Main方法都将被包装成一个可以被CLR宿主接受的非异步Main方法。由于这个新特性不需要CLR代码更改,所以异步Main方法其实只是一个语法糖。这样的设计允许后端与C#以前的版本兼容。要阅读更多的细节,请参阅Roslyn(译注:C#编译器)源代码仓库里的一篇文章:Aysnc Main

系列文章:

[译]C# 7系列,Part 2: Async Main 异步Main方法的更多相关文章

  1. Java多线程开发系列之五:Springboot 中异步请求方法的使用

    Springboot 中异步线程的使用在过往的后台开发中,我们往往使用java自带的线程或线程池,来进行异步的调用.这对于效果来说没什么,甚至可以让开发人员对底层的状况更清晰,但是对于代码的易读性和可 ...

  2. [译]C# 7系列,Part 9: ref structs ref结构

    原文:https://blogs.msdn.microsoft.com/mazhou/2018/03/02/c-7-series-part-9-ref-structs/ 背景 在之前的文章中,我解释了 ...

  3. [译]C# 7系列,Part 8: in Parameters in参数

    原文:https://blogs.msdn.microsoft.com/mazhou/2018/01/08/c-7-series-part-8-in-parameters/ 背景 默认情况下,方法参数 ...

  4. [译]C# 7系列,Part 1: Value Tuples 值元组

    Mark Zhou写了很不错的一系列介绍C# 7的文章,虽然是2年多年前发布的,不过对于不熟悉C# 7特性的同学来说,仍然有很高的阅读价值. 原文:https://blogs.msdn.microso ...

  5. [译]C# 7系列,Part 3: Default Literals 默认文本表达式

    原文:https://blogs.msdn.microsoft.com/mazhou/2017/06/06/c-7-series-part-3-default-literals/ C#的default ...

  6. [译]C# 7系列,Part 4: Discards 弃元

    原文:https://blogs.msdn.microsoft.com/mazhou/2017/06/27/c-7-series-part-4-discards/ 有时我们想要忽略一个方法返回的值,特 ...

  7. [译]C# 7系列,Part 5: private protected 访问修饰符

    原文:https://blogs.msdn.microsoft.com/mazhou/2017/10/05/c-7-series-part-5-private-protected/ C#有几个可访问性 ...

  8. [译]C# 7系列,Part 6: Read-only structs 只读结构

    原文:https://blogs.msdn.microsoft.com/mazhou/2017/11/21/c-7-series-part-6-read-only-structs/ 背景 在.NET世 ...

  9. [译]C# 7系列,Part 7: ref Returns ref返回结果

    原文:https://blogs.msdn.microsoft.com/mazhou/2017/12/12/c-7-series-part-7-ref-returns/ 背景 有两种方法可以将一个值传 ...

随机推荐

  1. python遍历所有盘符下的图片并拷贝下来

    最近在学习python,闲着无聊就试着写啦这个小的脚本,虽然有很多不足,但是还是收获不少. 该脚本的功能: ①遍历本地计算机中的所有盘符,并将名称记录下来: ②循环遍历盘符下的所有图片(当然这里可以根 ...

  2. 【数据结构】之栈(Java语言描述)

    在前面的[这篇文章]中,我简单介绍了栈这种数据结构的操作功能,并使用C语言对其进行了代码的编写. Java的JDK中默认为我们提供了栈这种数据结构的API—— Stack . Java中的Stack类 ...

  3. 【Android - 进阶】之Drawable简介

    Drawable是什么?Android给我们的解释是:“A general abstraction for 'something that can be drawn'.”,翻译过来就是:对于可以绘制的 ...

  4. num += num 与 num = num+ num

    a = 100def test(num): num += num print(num) test(a)print(a) 200100 这里 num += num 与 num = num+ num 不能 ...

  5. 循环双向链表-C语言实现

    直接贴出完整代码,每个函数的功能及部分代码的解释都在注释中,代码亲测可行 /* 2018.8.15 注意三点: 1.不要将循环写成if //很尴尬,主要是我犯了这个错误,找了半天还没找出来,第二天看的 ...

  6. 顺序表-C语言实现

    顺序存储线性表的结构体: #define MAXSIZE 100 //数组最大长度 typedef int ElemType; //元素类型 typedef struct //定义线性表结构体 { E ...

  7. 谈谈.net对象生命周期

     不用程序员操心的堆 — 托管堆         程序在计算机上跑着,就难免会占用内存资源来存储在程序运行过程中的数据,我们按照内存资源的存取方式将内存划分为堆内存和栈内存.    栈内存,通常使用的 ...

  8. redis数据类型--set

    set是String的一个无序集合,最大存储量2^32-1(大概40多亿) 1.操作命令:(xxx可以是任意字符串) sadd xxx a b c d e (添加一个或多个) smembers xxx ...

  9. 设计模式GOF23(结构型模式:代理模式,适配模式,桥接模式,组合模式,装饰模式,外观模式,享元模式)

    结构型模式: – 分类: • 适配器模式.代理模式.桥接模式.装饰模式.组合模式.外观模式.享元模式 – 核心作用:是从程序的结构上实现松耦合,从而可以扩大整体的类结构,用来解决更大的问题.   结构 ...

  10. 2019CCPC秦皇岛 F Forest Program

    队友过的:https://blog.csdn.net/liufengwei1/article/details/101632506 Forest Program Time Limit: 2000/100 ...