标签 .NET 下的文章

了解 .NET 开发平台启动和运行的基础知识。

.NET 框架由 Microsoft 于 2000 年发布。该平台的开源实现 Mono 在 21 世纪初成为了争议的焦点,因为微软拥有 .NET 技术的多项专利,并且可能使用这些专利来终止 Mono 项目。幸运的是,在 2014 年,微软宣布 .NET 开发平台从此成为 MIT 许可下的开源平台,并在 2016 年收购了开发 Mono 的 Xamarin 公司。

.NET 和 Mono 已经同时可用于 C#、F#、GTK+、Visual Basic、Vala 等的跨平台编程环境。使用 .NET 和 Mono 创建的程序已经应用于 Linux、BSD、Windows、MacOS、Android,甚至一些游戏机。你可以使用 .NET 或 Mono 来开发 .NET 应用。这两个都是开源的,并且都有活跃和充满活力的社区。本文重点介绍微软的 .NET 环境。

如何安装 .NET

.NET 下载被分为多个包:一个仅包含 .NET 运行时,另一个 .NET SDK 包含了 .NET Core 和运行时。根据架构和操作系统版本,这些包可能有多个版本。要开始使用 .NET 进行开发,你必须安装该 SDK。它为你提供了 dotnet 终端或 PowerShell 命令,你可以使用它们来创建和生成项目。

Linux

要在 Linux 上安装 .NET,首先将微软 Linux 软件仓库添加到你的计算机。

在 Fedora 上:

$ sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
$ sudo wget -q -O /etc/yum.repos.d/microsoft-prod.repo https://packages.microsoft.com/config/fedora/27/prod.repo

在 Ubuntu 上:

$ wget -q https://packages.microsoft.com/config/ubuntu/19.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
$ sudo dpkg -i packages-microsoft-prod.deb

接下来,使用包管理器安装 SDK,将 <X.Y> 替换为当前版本的 .NET 版本:

在 Fedora 上:

$ sudo dnf install dotnet-sdk-<X.Y>

在 Ubuntu 上:

$ sudo apt install apt-transport-https
$ sudo apt update
$ sudo apt install dotnet-sdk-<X.Y>

下载并安装所有包后,打开终端并输入下面命令确认安装:

$ dotnet --version
X.Y.Z

Windows

如果你使用的是微软 Windows,那么你可能已经安装了 .NET 运行时。但是,要开发 .NET 应用,你还必须安装 .NET Core SDK。

首先,下载安装程序。请认准下载 .NET Core 进行跨平台开发(.NET Framework 仅适用于 Windows)。下载 .exe 文件后,双击该文件启动安装向导,然后单击两下进行安装:接受许可证并允许安装继续。

 title=

然后,从左下角的“应用程序”菜单中打开 PowerShell。在 PowerShell 中,输入测试命令:

PS C:\Users\osdc> dotnet

如果你看到有关 dotnet 安装的信息,那么说明 .NET 已正确安装。

MacOS

如果你使用的是 Apple Mac,请下载 .pkg 形式的 Mac 安装程序。下载并双击该 .pkg 文件,然后单击安装程序。你可能需要授予安装程序权限,因为该软件包并非来自 App Store。

下载并安装所有软件包后,请打开终端并输入以下命令来确认安装:

$ dotnet --version
X.Y.Z

Hello .NET

dotnet 命令提供了一个用 .NET 编写的 “hello world” 示例程序。或者,更准确地说,该命令提供了示例应用。

首先,使用 dotnet 命令以及 newconsole 参数创建一个控制台应用的项目目录及所需的代码基础结构。使用 -o 选项指定项目名称:

$ dotnet new console -o hellodotnet

这将在当前目录中创建一个名为 hellodotnet 的目录。进入你的项目目录并看一下:

$ cd hellodotnet
$ dir
hellodotnet.csproj  obj  Program.cs

Program.cs 是一个空的 C# 文件,它包含了一个简单的 Hello World 程序。在文本编辑器中打开查看它。微软的 Visual Studio Code 是一个使用 dotnet 编写的跨平台的开源应用,虽然它不是一个糟糕的文本编辑器,但它会收集用户的大量数据(在它的二进制发行版的许可证中授予了自己权限)。如果要尝试使用 Visual Studio Code,请考虑使用 VSCodium,它是使用 Visual Studio Code 的 MIT 许可的源码构建的版本,而没有远程收集(请阅读此文档来禁止此构建中的其他形式追踪)。或者,只需使用现有的你最喜欢的文本编辑器或 IDE。

新控制台应用中的样板代码为:

using System;

namespace hellodotnet
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}

要运行该程序,请使用 dotnet run 命令:

$ dotnet run
Hello World!

这是 .NET 和 dotnet 命令的基本工作流程。这里有完整的 .NET C# 指南,并且都是与 .NET 相关的内容。关于 .NET 实战示例,请关注 Alex Bunardzic 在 opensource.com 中的变异测试文章。


via: https://opensource.com/article/19/9/getting-started-net

作者:Seth Kenlon 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

.NET Core 是微软提供的免费、跨平台和开源的开发框架,可以构建桌面应用程序、移动端应用程序、网络应用程序、物联网应用程序和游戏应用程序等。如果你是 Windows 平台下的 dotnet 开发人员的话,使用 .NET core 可以很轻松就设置好任何 Linux 和类 Unix 操作系统下的开发环境。本分步操作指南文章解释了如何在 Linux 中安装 .NET Core SDK 以及如何使用 .NET 开发出第一个应用程序。

Linux 中安装 .NET Core SDK

.NET Core 支持 GNU/Linux、Mac OS 和 Windows 系统,可以在主流的 GNU/Linux 操作系统上安装运行,包括 Debian、Fedora、CentOS、Oracle Linux、RHEL、SUSE/openSUSE 和 Ubuntu 。在撰写这篇教程时,其最新版本为 2.2

Debian 9 系统上安装 .NET Core SDK,请按如下步骤进行。

首先,需要注册微软的密钥,接着把 .NET 源仓库地址添加进来,运行的命令如下:

$ wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.asc.gpg
$ sudo mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/
$ wget -q https://packages.microsoft.com/config/debian/9/prod.list
$ sudo mv prod.list /etc/apt/sources.list.d/microsoft-prod.list
$ sudo chown root:root /etc/apt/trusted.gpg.d/microsoft.asc.gpg
$ sudo chown root:root /etc/apt/sources.list.d/microsoft-prod.list

注册好密钥及添加完仓库源后,就可以安装 .NET SDK 了,命令如下:

$ sudo apt-get update
$ sudo apt-get install dotnet-sdk-2.2

Debian 8 系统上安装:

增加微软密钥,添加 .NET 仓库源:

$ wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.asc.gpg
$ sudo mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/
$ wget -q https://packages.microsoft.com/config/debian/8/prod.list
$ sudo mv prod.list /etc/apt/sources.list.d/microsoft-prod.list
$ sudo chown root:root /etc/apt/trusted.gpg.d/microsoft.asc.gpg
$ sudo chown root:root /etc/apt/sources.list.d/microsoft-prod.list

安装 .NET SDK:

$ sudo apt-get update
$ sudo apt-get install dotnet-sdk-2.2

Fedora 28 系统上安装:

增加微软密钥,添加 .NET 仓库源:

$ sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
$ wget -q https://packages.microsoft.com/config/fedora/27/prod.repo
$ sudo mv prod.repo /etc/yum.repos.d/microsoft-prod.repo
$ sudo chown root:root /etc/yum.repos.d/microsoft-prod.repo

现在, 可以安装 .NET SDK 了:

$ sudo dnf update
$ sudo dnf install dotnet-sdk-2.2

Fedora 27 系统下:

增加微软密钥,添加 .NET 仓库源,命令如下:

$ sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
$ wget -q https://packages.microsoft.com/config/fedora/27/prod.repo
$ sudo mv prod.repo /etc/yum.repos.d/microsoft-prod.repo
$ sudo chown root:root /etc/yum.repos.d/microsoft-prod.repo

接着安装 .NET SDK ,命令如下:

$ sudo dnf update
$ sudo dnf install dotnet-sdk-2.2

CentOS/Oracle 版本的 Linux 系统上:

增加微软密钥,添加 .NET 仓库源,使其可用:

$ sudo rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm

更新源仓库,安装 .NET SDK:

$ sudo yum update
$ sudo yum install dotnet-sdk-2.2

openSUSE Leap 版本的系统上:

添加密钥,使仓库源可用,安装必需的依赖包,其命令如下:

$ sudo zypper install libicu
$ sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
$ wget -q https://packages.microsoft.com/config/opensuse/42.2/prod.repo
$ sudo mv prod.repo /etc/zypp/repos.d/microsoft-prod.repo
$ sudo chown root:root /etc/zypp/repos.d/microsoft-prod.repo

更新源仓库,安装 .NET SDK,命令如下:

$ sudo zypper update
$ sudo zypper install dotnet-sdk-2.2

Ubuntu 18.04 LTS 版本的系统上:

注册微软的密钥和 .NET Core 仓库源,命令如下:

$ wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb
$ sudo dpkg -i packages-microsoft-prod.deb

使 Universe 仓库可用:

$ sudo add-apt-repository universe

然后,安装 .NET Core SDK ,命令如下:

$ sudo apt-get install apt-transport-https
$sudo apt-get update
$ sudo apt-get install dotnet-sdk-2.2

Ubuntu 16.04 LTS 版本的系统上:

注册微软的密钥和 .NET Core 仓库源,命令如下:

$ wget -q https://packages.microsoft.com/config/ubuntu/16.04/packages-microsoft-prod.deb
$ sudo dpkg -i packages-microsoft-prod.deb

然后安装 .NET core SDK:

$ sudo apt-get install apt-transport-https
$ sudo apt-get update
$ sudo apt-get install dotnet-sdk-2.2

创建你的第一个应用程序

我们已经成功的在 Linux 机器中安装了 .NET Core SDK。是时候使用 dotnet 创建第一个应用程序了。

接下来的目的,我们会创建一个名为 ostechnixApp 的应用程序。为此,可以简单的运行如下命令:

$ dotnet new console -o ostechnixApp

示例输出:

Welcome to .NET Core!
---------------------
Learn more about .NET Core: https://aka.ms/dotnet-docs
Use 'dotnet --help' to see available commands or visit: https://aka.ms/dotnet-cli-docs

Telemetry
---------
The .NET Core tools collect usage data in order to help us improve your experience. The data is anonymous and doesn't include command-line arguments. The data is collected by Microsoft and shared with the community. You can opt-out of telemetry by setting the DOTNET_CLI_TELEMETRY_OPTOUT environment variable to '1' or 'true' using your favorite shell.

Read more about .NET Core CLI Tools telemetry: https://aka.ms/dotnet-cli-telemetry

ASP.NET Core
------------
Successfully installed the ASP.NET Core HTTPS Development Certificate.
To trust the certificate run 'dotnet dev-certs https --trust' (Windows and macOS only). For establishing trust on other platforms refer to the platform specific documentation.
For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054.
Getting ready...
The template "Console Application" was created successfully.

Processing post-creation actions...
Running 'dotnet restore' on ostechnixApp/ostechnixApp.csproj...
Restoring packages for /home/sk/ostechnixApp/ostechnixApp.csproj...
Generating MSBuild file /home/sk/ostechnixApp/obj/ostechnixApp.csproj.nuget.g.props.
Generating MSBuild file /home/sk/ostechnixApp/obj/ostechnixApp.csproj.nuget.g.targets.
Restore completed in 894.27 ms for /home/sk/ostechnixApp/ostechnixApp.csproj.

Restore succeeded.

正如上面的输出所示的,.NET 已经为我们创建一个控制台类型的应用程序。-o 参数创建了一个名为 “ostechnixApp” 的目录,其包含有存储此应用程序数据所必需的文件。

让我们切换到 ostechnixApp 目录,看看里面有些什么。

$ cd ostechnixApp/
$ ls
obj ostechnixApp.csproj Program.cs

可以看到有两个名为 ostechnixApp.csprojProgram.cs 的文件,以及一个名为 obj 的目录。默认情况下, Program.cs 文件包含有可以在控制台中运行的 “Hello World” 程序代码。可以看看此代码:

$ cat Program.cs 
using System;

namespace ostechnixApp
{
     class Program
     {
       static void Main(string[] args)
       {
         Console.WriteLine("Hello World!");
       }
   }
}

要运行此应用程序,可以简单的使用如下命令:

$ dotnet run
Hello World!

很简单,对吧?是的,就是如此简单。现在你可以在 Program.cs 这文件中写上自己的代码,然后像上面所示的执行。

或者,你可以创建一个新的目录,如例子所示的 mycode 目录,命令如下:

$ mkdir ~/.mycode
$ cd mycode/

然后运行如下命令,使其成为你的新开发环境目录:

$ dotnet new console

示例输出:

The template "Console Application" was created successfully.

Processing post-creation actions...
Running 'dotnet restore' on /home/sk/mycode/mycode.csproj...
Restoring packages for /home/sk/mycode/mycode.csproj...
Generating MSBuild file /home/sk/mycode/obj/mycode.csproj.nuget.g.props.
Generating MSBuild file /home/sk/mycode/obj/mycode.csproj.nuget.g.targets.
Restore completed in 331.87 ms for /home/sk/mycode/mycode.csproj.

Restore succeeded.

上的命令会创建两个名叫 mycode.csprojProgram.cs 的文件及一个名为 obj 的目录。用你喜欢的编辑器打开 Program.cs 文件, 删除或修改原来的 “hello world” 代码段,然后编写自己的代码。

写完代码,保存,关闭 Program.cs 文件,然后运行此应用程序,命令如下:

$ dotnet run

想要查看安装的 .NET core SDK 的版本的话,可以简单的运行:

$ dotnet --version
2.2.101

要获得帮助,请运行:

$ dotnet --help

使用微软的 Visual Studio Code 编辑器

要编写代码,你可以任选自己喜欢的编辑器。同时微软自己也有一款支持 .NET 的编辑器,其名为 “Microsoft Visual Studio Code”。它是一款开源、轻量级、功能强大的源代码编辑器。其内置了对 JavaScript、TypeScript 和 Node.js 的支持,并为其它语言(如 C++、C#、Python、PHP、Go)和运行时态(如 .NET 和 Unity)提供了丰富的扩展,已经形成一个完整的生态系统。它是一款跨平台的代码编辑器,所以在微软的 Windows 系统、GNU/Linux 系统和 Mac OS X 系统都可以使用。如果对其感兴趣,就可以使用。

想了解如何在 Linux 上安装和使用,请参阅以下指南。

Linux 中安装 Microsoft Visual Studio Code

关于 Visual Studio Code editor 中 .NET Core 和 .NET Core SDK 工具的使用,此网页有一些基础的教程。想了解更多就去看看吧。

Telemetry

默认情况下,.NET core SDK 会采集用户使用情况数据,此功能被称为 Telemetry。采集数据是匿名的,并根据知识共享署名许可分享给其开发团队和社区。因此 .NET 团队会知道这些工具的使用状况,然后根据统计做出决策,改进产品。如果你不想分享自己的使用信息的话,可以使用顺手的 shell 工具把名为 DOTNET_CLI_TELEMETRY_OPTOUT 的环境变量参数设置为 1true,这样就简单的关闭此功能了。

就这样。你已经知道如何在各 Linux 平台上安装 .NET Core SDK 以及知道如何创建基本的应用程序了。想了解更多 .NET 使用知识的话,请参阅此文章末尾给出的链接。

会爆出更多干货的。敬请关注!

祝贺下!

资源


via: https://www.ostechnix.com/how-to-install-microsoft-net-core-sdk-on-linux/

作者:SK 选题:lujun9972 译者:runningwater 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

朋友们,你们好!

近来,我听到了大量的关于新出的 .NET Core 和其性能的讨论,尤其在 Web 服务方面的讨论更甚。

因为是新出的,我不想立马就比较两个不同的东西,所以我耐心等待,想等发布更稳定的版本后再进行。

本周一(8 月 14 日),微软发布 .NET Core 2.0 版本,因此,我准备开始。您们认为呢?

如前面所提的,我们会比较它们相同的东西,比如应用程序、预期响应及运行时的稳定性,所以我们不会把像对 JSON 或者 XML 的编码、解码这些烦多的事情加入比较游戏中来,仅仅只会使用简单的文本消息。为了公平起见,我们会分别使用 Go 和 .NET Core 的 MVC 架构模式

参赛选手

Go (或称 Golang): 是一种快速增长的开源编程语言,旨在构建出简单、快捷和稳定可靠的应用软件。

用于支持 Go 语言的 MVC web 框架并不多,还好我们找到了 Iris ,可胜任此工作。

Iris: 支持 Go 语言的快速、简单和高效的微型 Web 框架。它为您的下一代网站、API 或分布式应用程序奠定了精美的表现方式和易于使用的基础。

C#: 是一种通用的、面向对象的编程语言。其开发团队由 Anders Hejlsberg 领导。

.NET Core: 跨平台,可以在极少时间内开发出高性能的应用程序。

可从 https://golang.org/dl下载Go,从https://www.microsoft.com/net/core 下载 .NET Core。

在下载和安装好这些软件后,还需要为 Go 安装 Iris。安装很简单,仅仅只需要打开终端,然后执行如下语句:

go get -u github.com/kataras/iris

基准

硬件

  • 处理器: Intel(R) Core(TM) i7–4710HQ CPU @ 2.50GHz 2.50GHz
  • 内存: 8.00 GB

软件

两个应用程序都通过请求路径 “api/values/{id}” 返回文本“值”。

.NET Core MVC

Logo 由 Pablo Iglesias 设计。

可以使用 dotnet new webapi 命令创建项目,其 webapi 模板会为您生成代码,代码包含 GET 请求方法的 返回“值”

源代码:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace netcore_mvc
{
    public class Program
    {
        public static void Main(string[] args)
        {
            BuildWebHost(args).Run();
        }

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace netcore_mvc
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvcCore();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseMvc();
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;

namespace netcore_mvc.Controllers
{
    // ValuesController is the equivalent
    // `ValuesController` of the Iris 8.3 mvc application.
    [Route("api/[controller]")]
    public class ValuesController : Controller
    {
        // Get handles "GET" requests to "api/values/{id}".
        [HttpGet("{id}")]
        public string Get(int id)
        {
            return "value";
        }

        // Put handles "PUT" requests to "api/values/{id}".
        [HttpPut("{id}")]
        public void Put(int id, [FromBody]string value)
        {
        }

        // Delete handles "DELETE" requests to "api/values/{id}".
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
        }
    }
}

运行 .NET Core web 服务项目:

$ cd netcore-mvc
$ dotnet run -c Release
Hosting environment: Production
Content root path: C:\mygopath\src\github.com\kataras\iris\_benchmarks\netcore-mvc
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.

运行和定位 HTTP 基准工具:

$ bombardier -c 125 -n 5000000 http://localhost:5000/api/values/5
Bombarding http://localhost:5000/api/values/5 with 5000000 requests using 125 connections
 5000000 / 5000000 [=====================================================] 100.00% 2m3s
Done!
Statistics        Avg      Stdev        Max
  Reqs/sec     40226.03    8724.30     161919
  Latency        3.09ms     1.40ms   169.12ms
  HTTP codes:
    1xx - 0, 2xx - 5000000, 3xx - 0, 4xx - 0, 5xx - 0
    others - 0
  Throughput:     8.91MB/s
Iris MVC

Logo 由 Santosh Anand 设计。

源代码:

package main

import (
    "github.com/kataras/iris"
    "github.com/kataras/iris/_benchmarks/iris-mvc/controllers"
)

func main() {
    app := iris.New()
    app.Controller("/api/values/{id}", new(controllers.ValuesController))
    app.Run(iris.Addr(":5000"), iris.WithoutVersionChecker)
}
package controllers

import "github.com/kataras/iris/mvc"

// ValuesController is the equivalent
// `ValuesController` of the .net core 2.0 mvc application.
type ValuesController struct {
    mvc.Controller
}

// Get handles "GET" requests to "api/values/{id}".
func (vc *ValuesController) Get() {
    // id,_ := vc.Params.GetInt("id")
    vc.Ctx.WriteString("value")
}

// Put handles "PUT" requests to "api/values/{id}".
func (vc *ValuesController) Put() {}

// Delete handles "DELETE" requests to "api/values/{id}".
func (vc *ValuesController) Delete() {}

运行 Go web 服务项目:

$ cd iris-mvc
$ go run main.go
Now listening on: http://localhost:5000
Application started. Press CTRL+C to shut down.

运行和定位 HTTP 基准工具:

$ bombardier -c 125 -n 5000000 http://localhost:5000/api/values/5
Bombarding http://localhost:5000/api/values/5 with 5000000 requests using 125 connections
 5000000 / 5000000 [======================================================] 100.00% 47s
Done!
Statistics        Avg      Stdev        Max
  Reqs/sec    105643.81    7687.79     122564
  Latency        1.18ms   366.55us    22.01ms
  HTTP codes:
    1xx - 0, 2xx - 5000000, 3xx - 0, 4xx - 0, 5xx - 0
    others - 0
  Throughput:    19.65MB/s

想通过图片来理解的人,我也把我的屏幕截屏出来了!

请点击这儿可以看到这些屏幕快照。

总结

  • 完成 5000000 个请求的时间 - 越短越好。
  • 请求次数/每秒 - 越大越好。
  • 等待时间 — 越短越好。
  • 吞吐量 — 越大越好。
  • 内存使用 — 越小越好。
  • LOC (代码行数) — 越少越好。

.NET Core MVC 应用程序,使用 86 行代码,运行 2 分钟 8 秒,每秒接纳 39311.56 个请求,平均 3.19ms 等待,最大时到 229.73ms,内存使用大约为 126MB(不包括 dotnet 框架)。

Iris MVC 应用程序,使用 27 行代码,运行 47 秒,每秒接纳 105643.71 个请求,平均 1.18ms 等待,最大时到 22.01ms,内存使用大约为 12MB。

还有另外一个模板的基准,滚动到底部。

2017 年 8 月 20 号更新

Josh ClarkScott Hanselman在此 tweet 评论上指出,.NET Core Startup.cs 文件中 services.AddMvc(); 这行可以替换为 services.AddMvcCore();。我听从他们的意见,修改代码,重新运行基准,该文章的 .NET Core 应用程序的基准输出已经修改。

@topdawgevh @shanselman 他们也在使用 AddMvc() 而不是 AddMvcCore() ...,难道都不包含中间件?

 —  @clarkis117

@clarkis117 @topdawgevh Cool @MakisMaropoulos @benaadams @davidfowl 我们来看看。认真学习下怎么使用更简单的性能默认值。

 —  @shanselman

@shanselman @clarkis117 @topdawgevh @benaadams @davidfowl @shanselman @benaadams @davidfowl 谢谢您们的反馈意见。我已经修改,更新了结果,没什么不同。对其它的建议,我非常欢迎。

 —  @MakisMaropoulos

它有点稍微的不同但相差不大(从 8.61MB/s 到 8.91MB/s)

想要了解跟 services.AddMvc() 标准比较结果的,可以点击这儿

想再多了解点儿吗?

我们再制定一个基准,产生 1000000 次请求,这次会通过视图引擎由模板生成 HTML 页面。

.NET Core MVC 使用的模板

using System;

namespace netcore_mvc_templates.Models
{
    public class ErrorViewModel
    {
        public string Title { get; set; }
        public int Code { get; set; }
    }
}
 using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using netcore_mvc_templates.Models;

namespace netcore_mvc_templates.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

        public IActionResult About()
        {
            ViewData["Message"] = "Your application description page.";

            return View();
        }

        public IActionResult Contact()
        {
            ViewData["Message"] = "Your contact page.";

            return View();
        }

        public IActionResult Error()
        {
            return View(new ErrorViewModel { Title = "Error", Code = 500});
        }
    }
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace netcore_mvc_templates
{
    public class Program
    {
        public static void Main(string[] args)
        {
            BuildWebHost(args).Run();
        }

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace netcore_mvc_templates
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            /*  An unhandled exception was thrown by the application.
                System.InvalidOperationException: No service for type
                'Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionaryFactory' has been registered.
                Solution: Use AddMvc() instead of AddMvcCore() in Startup.cs and it will work.
            */
            // services.AddMvcCore();
            services.AddMvc();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseStaticFiles();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}
/*
wwwroot/css
wwwroot/images
wwwroot/js
wwwroot/lib
wwwroot/favicon.ico


Views/Shared/_Layout.cshtml
Views/Shared/Error.cshtml

Views/Home/About.cshtml
Views/Home/Contact.cshtml
Views/Home/Index.cshtml

These files are quite long to be shown in this article but you can view them at: 
https://github.com/kataras/iris/tree/master/_benchmarks/netcore-mvc-templates

运行 .NET Core 服务项目:

$ cd netcore-mvc-templates
$ dotnet run -c Release
Hosting environment: Production
Content root path: C:\mygopath\src\github.com\kataras\iris\_benchmarks\netcore-mvc-templates
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.

运行 HTTP 基准工具:

Bombarding http://localhost:5000 with 1000000 requests using 125 connections
 1000000 / 1000000 [====================================================] 100.00% 1m20s
Done!
Statistics Avg Stdev Max
 Reqs/sec 11738.60 7741.36 125887
 Latency 10.10ms 22.10ms 1.97s
 HTTP codes:
 1xx — 0, 2xx — 1000000, 3xx — 0, 4xx — 0, 5xx — 0
 others — 0
 Throughput: 89.03MB/s

Iris MVC 使用的模板

package controllers

import "github.com/kataras/iris/mvc"

type AboutController struct{ mvc.Controller }

func (c *AboutController) Get() {
    c.Data["Title"] = "About"
    c.Data["Message"] = "Your application description page."
    c.Tmpl = "about.html"
}
package controllers

import "github.com/kataras/iris/mvc"

type ContactController struct{ mvc.Controller }

func (c *ContactController) Get() {
    c.Data["Title"] = "Contact"
    c.Data["Message"] = "Your contact page."
    c.Tmpl = "contact.html"
}
package models

// HTTPError a silly structure to keep our error page data.
type HTTPError struct {
    Title string
    Code  int
}
package controllers

import "github.com/kataras/iris/mvc"

type IndexController struct{ mvc.Controller }

func (c *IndexController) Get() {
    c.Data["Title"] = "Home Page"
    c.Tmpl = "index.html"
}
package main

import (
    "github.com/kataras/iris/_benchmarks/iris-mvc-templates/controllers"

    "github.com/kataras/iris"
    "github.com/kataras/iris/context"
)

const (
    // templatesDir is the exactly the same path that .NET Core is using for its templates,
    // in order to reduce the size in the repository.
    // Change the "C\\mygopath" to your own GOPATH.
    templatesDir = "C:\\mygopath\\src\\github.com\\kataras\\iris\\_benchmarks\\netcore-mvc-templates\\wwwroot"
)

func main() {
    app := iris.New()
    app.Configure(configure)

    app.Controller("/", new(controllers.IndexController))
    app.Controller("/about", new(controllers.AboutController))
    app.Controller("/contact", new(controllers.ContactController))

    app.Run(iris.Addr(":5000"), iris.WithoutVersionChecker)
}

func configure(app *iris.Application) {
    app.RegisterView(iris.HTML("./views", ".html").Layout("shared/layout.html"))
    app.StaticWeb("/public", templatesDir)
    app.OnAnyErrorCode(onError)
}

type err struct {
    Title string
    Code  int
}

func onError(ctx context.Context) {
    ctx.ViewData("", err{"Error", ctx.GetStatusCode()})
    ctx.View("shared/error.html")
}
/*
../netcore-mvc-templates/wwwroot/css
../netcore-mvc-templates/wwwroot/images
../netcore-mvc-templates/wwwroot/js
../netcore-mvc-templates/wwwroot/lib
../netcore-mvc-templates/wwwroot/favicon.ico
views/shared/layout.html
views/shared/error.html
views/about.html
views/contact.html
views/index.html
These files are quite long to be shown in this article but you can view them at: 
https://github.com/kataras/iris/tree/master/_benchmarks/iris-mvc-templates
*/

运行 Go 服务项目:

$ cd iris-mvc-templates
$ go run main.go
Now listening on: http://localhost:5000
Application started. Press CTRL+C to shut down.

运行 HTTP 基准工具:

Bombarding http://localhost:5000 with 1000000 requests using 125 connections
 1000000 / 1000000 [======================================================] 100.00% 37s
Done!
Statistics Avg Stdev Max
 Reqs/sec 26656.76 1944.73 31188
 Latency 4.69ms 1.20ms 22.52ms
 HTTP codes:
 1xx — 0, 2xx — 1000000, 3xx — 0, 4xx — 0, 5xx — 0
 others — 0
 Throughput: 192.51MB/s

总结

  • 完成 1000000 个请求的时间 - 越短越好。
  • 请求次数/每秒 - 越大越好。
  • 等待时间 — 越短越好。
  • 内存使用 — 越小越好。
  • 吞吐量 — 越大越好。

.NET Core MVC 模板应用程序,运行 1 分钟 20 秒,每秒接纳 11738.60 个请求,同时每秒生成 89.03M 页面,平均 10.10ms 等待,最大时到 1.97s,内存使用大约为 193MB(不包括 dotnet 框架)。

Iris MVC 模板应用程序,运行 37 秒,每秒接纳 26656.76 个请求,同时每秒生成 192.51M 页面,平均 1.18ms 等待,最大时到 22.52ms,内存使用大约为 17MB。

接下来呢?

这里有上面所示的源代码,请下载下来,在您本地以同样的基准运行,然后把运行结果在这儿给大家分享。

想添加 Go 或 C# .net core WEB 服务框架到列表的朋友请向这个仓库_benchmarks 目录推送 PR。

我也需要亲自感谢下 dev.to 团队,感谢把我的这篇文章分享到他们的 Twitter 账户。

感谢大家真心反馈,玩得开心!

更新 : 2017 年 8 月 21 ,周一

很多人联系我,希望看到一个基于 .NET Core 的较低级别 Kestrel 的基准测试文章。

因此我完成了,请点击下面的链接来了解 Kestrel 和 Iris 之间的性能差异,它还包含一个会话存储管理基准!


via: https://hackernoon.com/go-vs-net-core-in-terms-of-http-performance-7535a61b67b8

作者:Gerasimos Maropoulos 译者:runningwater 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

就在两年前,微软做了一件令人意想不到的事情:它宣称将开源其 .Net 开发框架,这包括 .Net CoreASP.Net 等。这份公告非常令人吃惊,因为微软长久以来一直仇视开源项目,担忧开源软件破坏其软件生态。

随着微软 CEO 纳德拉宣称“微软爱 Linux”,微软在开源方面的举措频频,不仅仅在 GitHub 上其名下的几个仓库活跃非凡,而且也和各种开源厂商积极展开合作

不管微软积极拥抱开源背后的想法是什么,或许是想通过开源销售更多的软件或者云服务,也有可能是想吸引更多的开发者到微软平台上,但是目前看起来微软这步棋是下对了。从微软开源 .NetASP.Net 之后的分析看,微软的开源战略已经值回票价了。

微软现在将 .Net Core 定位为跨平台开发框架,不只是 Windows,而且也延伸到了 MacOS 和 Linux 平台之上。.Net Core RC1 是 2015 年 11 月发布到 GitHub 上的,而今年 6 月就发布了 1.0 版本。开发者们对此表示认可,微软合作伙伴总监项目经理 Scott Hunter 如是说:

“40% 的 .Net Core 客户是新进入该平台的用户,这就是我们(开源)的目的,我们希望吸引新的用户。”

由于 .Net Core 的开源,过去一年以来, .Net 的开发者增加了 61%。 Hunter 在 11 月的一次讲演中提到,GitHub 上 .Net 上的开发活跃度增长极快。
虽然 .Net Core 并没有直接给微软带来收入,但是其潜在地增加了收益。Rob Sanfilippo 说,“可以说,这项技术间接地通过 Azure 服务和微软开发者工具增加了微软的收入。”。

程序员们表现活跃

.Net 程序员和博客作者 Matt Warren 把.Net 的开源称之为“成功”。其数据明确地显示社区积极地参与了微软在 GitHub 上开源的多个仓库的活动。

“开源社区汇报了问题和建议,并通过发送拉取请求(PR)而实际贡献了代码,经过一段时间之后,这些代码就会被包括到产品里面,而社区的贡献量还在持续增长”,Warren 说,“我积极跟踪和参与了 CoreCLR.Net Core Lab 这些仓库的讨论,因此获得了社区贡献的第一手资料。”

微软的举措是否完全成功还不能完全定论,未来或许还有变数,但是这终究是从封闭走向开放的一步。他说,“我的意思是,他们并不是仅仅把源代码放在那里就行了,而是努力让社区可以参与进来。”

微软最近发布的 Visual Studio for Mac 也为 .Net Core 带来了利好

“这是 Visual Studio IDE 首次发布到非 Windows 平台上(Visual Studio Code 是不同的技术,而且它根本不算 IDE),它是基于微软收购的 Xamarin 的技术,重点关注于 .Net Core 开发”,Sanfillippo 说,“这次发布近一步带动了 .Net Core 的发展。”

微软最近也准备在 Visual Studio 2017 IDE 中增强 .Net Core 工具,包括简化 .Net Core 项目文件的格式。

微软开源 .Net 让外界对它的观感有所改变, Warren 说,“现在感觉(微软)更开放和更平易近人了。”

相对于某些公司,虽然开源社区还对微软抱有一定的疑虑,但是显然,微软已经不是开源社区最敌视的公司了。

参考:CIOMatt Warrenmicrosoft

前一篇文章中,我们了解了微软在开源了 .NET 框架中最大一部分一年以来社区的参与情况。

接下来,我们将继续重复这个分析,但是这次我们将针对 ASP.NET 系列项目进行分析:

  • MVC - 通过分成“模型-视图-控制器(MVC)”等不同的概念部分来构建动态网站的框架,包括合并的 MVC、 Web API、 和 Web Pages w/ Razor。
  • DNX - DNX(一个 .NET 扩展环境)包含了用于启动和运行应用的代码,包括编译系统、SDK 工具和原生 CLR 宿主。
  • EntityFramework - 微软推荐用于新的 .NET 应用的数据访问技术。
  • KestrelHttpServer - 一个基于 libuv 的 ASP.NET 5 的 Web 服务器。

方法

上一篇中,我们首先把 问题 issue / 拉取请求 PR 分成 拥有者 Owner 协作者 Collaborator 社区 Community 三类。然而这有一些问题,正如在评论中指出的那样,有几个人并非微软雇员,但是由于其在某个项目上的积极贡献也被列为了协作者,比如 @kangaroo@benpye

为了解决这个问题,我决定分成两类:

  • 微软
  • 社区

这是可行的,因为(基本上)所有的微软雇员都会在其 GitHub 个人页面上标记其为微软雇员,比如:

David Fowler Profile

这种情况有一些例外,比如 @shanselman 显然是在微软工作,不过这种情况很好解决。

结果

在结束了所有分析之后,我得到了结果。总的来说,超过 60% 的“ 发现的问题 Issues Created ”和 33% 的“ 合并的 PR Merged Pull Requests ”来自社区。然而,PR 的占比受到了 Entity Framework 项目中微软雇员超高的 PR 数量的影响,从而有些不能准确反映情况。如果忽略这个项目,社区贡献的 PR 将占到 44%。

发现的问题(2013/11 - 2015/12)

项目微软社区合计
aspnet/MVC71613802096
aspnet/dnx89712062103
aspnet/EntityFramework106614272493
aspnet/KestrelHttpServer89176265
合计276841896957

合并的 PR(2013/11 - 2015/12)

项目微软社区合计
aspnet/MVC385228613
aspnet/dnx406368774
aspnet/EntityFramework9372251162
aspnet/KestrelHttpServer6988157
合计17989092706

备注:我包括了 Kestrel Http Server 项目,因为它是一个有趣的例子。当前它的第一号贡献者 Ben Adams 并非微软雇员,他为改善其内存使用做出了很大的贡献,让 Kestrel 可以每秒钟接受更多的请求。

通过观察随时间推移的变化,可以很清楚的看到社区(浅色条)在过去两年(2013/11 - 2015/12)来的参与情况,看起来并不像是趋于停止。

每月发现的问题数 - 按提交者

每月问题数 - 按提交者(微软或社区)

此外,虽然社区参与情况可以很容易地从每月发现的问题数上看出来,不过从合并的 PR 数上也可以再次印证这两年来的趋势。

每月合并的 PR 数 - 按提交者

每月合并 PR 数 - 按提交者(微软或社区)

贡献总数

每个项目的贡献人数也很有意思。通过这个你可以看到社区贡献者的实际规模,并不是少量的人做了大量的工作,而是这些工作由大量的人分散完成的。

这个表格展示了每个项目中发现问题和提交了被合并的 PR 的人数:

项目微软社区合计
aspnet/MVC39395434
aspnet/dnx46421467
aspnet/EntityFramework31570601
aspnet/KestrelHttpServer2295117
合计13814811619

FSharp

在我的第一篇文章的评论中,Isaac Abraham 指正说:

.NET 的一部分已经开源一年多了,F# 编译器和 FSharp.Core 已经开源一段时间了。

所以,为了解决这个问题,我去了解了一下主要的 FSharp 仓库:

按 Isaac 的解释,他们之间的关系是:

... visualfsharp 是微软自己的 Visual F# 版本仓库。而另外一个是社区管理的一个。前一个是直接作为 Visual Studio 其中的 Visual F# 工具;而后一个则是类似 Xamarin 的东西。这里有个(稍微过时的)解析它们关系的图表,以及另外一个有用的资源:http://fsharp.github.io/

FSharp - 发现的问题(2010/12 - 2015/12)

项目微软社区合计
fsharp/fsharp9312321
microsoft/visualfsharp161367528
合计170679849

FSharp - 合并的 PR(2011/5 - 2015/12)

项目微软社区合计
fsharp/fsharp27134161
microsoft/visualfsharp363369
合计63167230

结论

我认为,公平地说社区已经对微软越来越多地开源其代码的动作做出了回应。在几个项目上社区花费了大量时间,做出了显著的贡献。虽然你可以说微软也花费了大量的时间来开源,但是看起来 .NET 开发人员很喜欢他们做的事情,体现了可观的社区响应。

大约一年前,微软宣布开源了 .NET 框架的大部分。当时,Scott Hanselman 使用微软 Power BI 对代码库做了一个漂亮的分析。 现在一年过去了,我想要试试对以下问题做个解答:

微软开源了 .NET 框架的大部分之后,社区参与贡献了多少?

我着眼于以下三个项目做了分析,它们是 .NET 生态系统中最主要部分之一,也是 .NET 基金会内 最活跃/收藏/分支的项目之一:

  • Roslyn – .NET 编译器平台,提供了开源的 C# 和 Visual Basic 编译器,以及丰富的代码分析 API。
  • CoreCLR – .NET Core 运行时环境和底层库(mscorlib),它包括垃圾回收、JIT 编译器、基本的 .NET 数据类型和许多底层类。
  • CoreFX – .NET Core 基础库,包括 collections、文件系统、console、XML、异步以及其它方面的类。

数据来自哪里?

GitHub 自身已经内建了很多漂亮的图表了,你可以看看这一年来每月提交数的图表:

Commits Per Month

还可以看看每月动态

github stats - monthly pulse

但是要回答上面的问题,我需要更多的数据。幸运的是, GitHub 提供了非常全面的 API, 再配合上出色的 Octokit.net 库以及 brilliant LINQPad,我就很容易的得到了我所需的全部数据。如果你想要自己试试这些 API ,这儿有个示例的 LINQPad 脚本

然而,仅仅知道它的每月 “ 问题 issue 数量” 或 “接受的PR( 拉取请求 Pull Request )”并没有太大用处,这并不能告诉我们是谁提交了这些问题或 PR。 幸运的是, GitHub 典型的用户是有分类的,比如下图来自 Roslyn 第 670 号问题 ,我们可以看到是哪种类型的用户提交的备注:“ 拥有者 Owner ”、 “ 协作者 Collaborator ” 或者为空——这就是“社区”成员,比如下面的某人(我觉得)并没有在微软工作。

owner collaborator or community

结果呢?

现在我们可以得到我们所需的数据,也就可以生成结果了。

全部问题 - 按提交者分组

项目拥有者协作者社区全部
Roslyn481186715963944
CoreCLR86298487871
CoreFX3349117351980
全部90130762818

这里你可以看到拥有者和协作者在某些情况下占有主导地位,比如,在 Roslyn 项目中 60% 的问题是他们汇报的。但是在另外的例子中社区非常活跃,特别是在 CoreCLR 项目中社区成员汇报的问题超过了拥有者/协作者之和。造成这种情况的部分原因是项目的不同, CoreCLR 是 .NET 框架中最引人注目的部分,因为它包含了 .NET 开发者日常使用的大部分库,所以并不用对社区提交了很多改进建议和错误修复的事情感到惊奇。 另外, CoreCLR 已经出现了较长时间,社区已经使用了一段时间,也能找到它的一些不足的部分。而 Roslyn 则相对较新一些,还没有被太多的使用过,而且找到一个编译器的 bug 显然会更难。

全部已接受的 PR - 按提交者分组

项目拥有者协作者社区全部
Roslyn46520931182676
CoreCLR3785672011146
CoreFX51614094642389
全部13594069783

但是,如果我们来看一下已接受的 PR ,可以看到在这三个项目中社区的贡献量非常低,仅仅只有 12% 左右。不过,这并不令人吃惊,因为 PR 需要达到相当高的水准才能被接受。如果项目采用这种机制,首先你必须找到一个 “需要解决” up for grabs 的问题,然后如果你要改变 API 就必须通过代码审查,最后你必须在代码审查中符合可比性/性能提升/正确性等。所以,实际上 12% 是个相当不错的结果,接受的 PR 解决了不少的问题,特别是考虑到大部分贡献都是社区成员在工作之余完成的。

更新:关于对“需要解决”的要求,参见 David Kean这个评论,以及这条推来了解更多信息。“需要解决”是一个准则,旨在帮助新手,但是并不是必需的,你可以提交一个解决问题的 PR 而不打上这个标签。

最后,如果你看一下每月的数量(参见下面的两张图,点击放大),很难找到特定的趋势,或者说,社区肯定会随着时间的变化或多或少的做出贡献。不过,你也可以说,过去一年来社区一直在做贡献,而且看起来还会继续贡献下去。这不是仅仅出现在项目刚刚开源后的一次性喷发,而是一整年以来的贡献的持续水平。

每月的问题数 - 按提交者分组

Issues Per Month - By Submitter (Owner, Collaborator or Community)

每月接受的 PR - 按提交者分组

Merged Pull Requests Per Month - By Submitter (Owner, Collaborator or Community)

前 20 的问题标签

最后一件我想对我拥有的这些数据所做的事情是找到那些最流行的问题标签,这可以揭示从三个项目开源以来哪种类型的工作不断出现。

Top 20 Issue Labels

以下是关于这些结果的一些看法: