Asp.net Core 入门实战

 

Asp.Net Core 是开源,跨平台,模块化,快速而简单的Web框架.

Asp.net Core官网的一个源码合集,方便一次性Clone

目录

持续更新,也可以通过我的网站访问,欢迎探讨交流

快速入门

安装

下载安装 .NET SDK

查看dotnet sdk 版本

$ dotnet --version`
2.1.4

创建项目目录

$ mkdir study
$ cd study

使用 dotnet new 命令创建项目

$ dotnet new console -n Demo
$ cd Demo

在 VS Code中打开Demo文件夹

一个最小的应用

打开 Program.cs

using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; namespace Demo
{
class Program
{
static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseStartup<Startup>()
.Build();
host.Run();
}
} class Startup
{
public void Configure(IApplicationBuilder app)
{
app.Run(async context =>
{
await context.Response.WriteAsync("Hello, World!");
});
}
}
}

安装相关的Nuget包

$ dotnet add package Microsoft.AspNetCore.Hosting --version 2.0.1
$ dotnet add package Microsoft.AspNetCore.Server.Kestrel --version 2.0.1

下载依赖项

$ dotnet restore

运行

$ dotnet run

输出结果:

Hosting environment: Production
Content root path: C:\netcore\study\Demo\bin\Debug\netcoreapp2.0\
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.

项目模板

根据指定的模板,创建新的项目、配置文件或解决方案。

$ dotnet new -h
使用情况: new [选项] 选项:
-h, --help 显示有关此命令的帮助。
-l, --list 列出包含指定名称的模板。如果未指定名称,请列出所有模板。
-n, --name 正在创建输出的名称。如果未指定任何名称,将使用当前目录的名 称。
-o, --output 要放置生成的输出的位置。
-i, --install 安装源或模板包。
-u, --uninstall 卸载一个源或模板包。
--type 基于可用的类型筛选模板。预定义的值为 "project"、"item" 或 "other"。
--force 强制生成内容,即使该内容会更改现有文件。
-lang, --language 指定要创建的模板的语言。 模板 短名称 语言 标记
-------------------------------------------------------------------------------- ------------------------
Console Application console [C#], F#, VB Common/Console
Class library classlib [C#], F#, VB Common/Library
Unit Test Project mstest [C#], F#, VB Test/MSTest
xUnit Test Project xunit [C#], F#, VB Test/xUnit
ASP.NET Core Empty web [C#], F# Web/Empty
ASP.NET Core Web App (Model-View-Controller) mvc [C#], F# Web/MVC
ASP.NET Core Web App razor [C#] Web/MVC/Razor Pages
ASP.NET Core with Angular angular [C#] Web/MVC/SPA
ASP.NET Core with React.js react [C#] Web/MVC/SPA
ASP.NET Core with React.js and Redux reactredux [C#] Web/MVC/SPA
ASP.NET Core Web API webapi [C#], F# Web/WebAPI
global.json file globaljson Config
NuGet Config nugetconfig Config
Web Config webconfig Config
Solution File sln Solution
Razor Page page Web/ASP.NET
MVC ViewImports viewimports Web/ASP.NET
MVC ViewStart viewstart Web/ASP.NET Examples:
dotnet new mvc --auth Individual
dotnet new page --namespace
dotnet new --help

使用dotnet new 选择 console 模板 创建项目

$ dotnet new console -n Demo
$ cd Demo

创建后的项目文档结构是

.
├── Demo
│ ├── Demo.csproj
│ └── Program.cs

路由

启用,配置路由

using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection; namespace Demo { class Startup {
public void ConfigureServices (IServiceCollection services) {
//启用路由
services.AddRouting ();
}
public void Configure (IApplicationBuilder app) {
//配置路由
app.UseRouter (routes => {
//根路由 (/)
routes.MapGet("", context =>
{
return context.Response.WriteAsync("Hello, World!");
});
//在根路由 (/) 上,配置 /hello Get请求的路由
routes.MapGet ("hello", context => {
return context.Response.WriteAsync ("Got a Get request at /hello");
});
});
}
}
}

安装相关的Nuget包

$ dotnet add package Microsoft.AspNetCore.Routing --version 2.0.1

下载依赖项

$ dotnet restore

运行

$ dotnet run

访问 http://localhost:5000/hello ,输出结果:

Got a Get request at /hello

对 /user 路由的 POST 请求进行响应:

routes.MapPost("hello", context => {
return context.Response.WriteAsync ("Got a Post request at /hello");
})

对 /user 路由的 PUT 请求进行响应:

routes.MapPut("hello", context => {
return context.Response.WriteAsync ("Got a Put request at /hello");
})

对 /user 路由的 DELETE 请求进行响应:

routes.MapDelete("hello", context => {
return context.Response.WriteAsync ("Got a Dlete request at /hello");
})

静态文件

启用,配置静态资源

创建 wwwroot文件夹

$ mkdir wwwroot
$ cd wwwroot

复制 index.html 到 wwwroot目录

$ mkdir images
$ cd images

复制 favicon.png 到 images文件夹下

项目结构图如下:
.
├── Demo
│ ├── wwwroot
│ │ ├── images
│ │ │ ├── favicon.png
│ │ ├── index.html
│ ├── Demo.csproj
│ └── Program.cs

更改 Program.cs,设置ContentRoot路径为当前项目根目录,启用静态资源

using System;
using System.IO;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection; namespace Demo {
class Program {
static void Main (string[] args) {
Console.WriteLine (AppContext.BaseDirectory);
var host = new WebHostBuilder ()
.UseKestrel ()
//设置 ContentRoot, ContentRoot是任何资源的根路径,比如页面和静态资源
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.Build ();
host.Run ();
}
} class Startup {
public void Configure (IApplicationBuilder app) {
//使用静态资源,默认的目录是 /wwwroot
app.UseStaticFiles ();
}
}
}

运行

http://localhost:5000/index.html

http://localhost:5000/images/favicon.png

配置其他文件夹

新建文件夹myfiles

$ mkdir myfiles
$ cd myfiles

创建一个新的 index.html到myfiles文件夹,配置并使用myfiles文件夹

app.UseStaticFiles (new StaticFileOptions {
FileProvider = new PhysicalFileProvider (
Path.Combine (Directory.GetCurrentDirectory (), "myfiles")),
RequestPath = "/myfiles"
});

运行

http://localhost:5000/myfiles/index.html

页面渲染

Razor模板引擎

Asp.net Core自带的模板引擎是 Razor模板引擎,传统的Razor页面以cshtml结尾, 阅读Razor语法
遗憾的是Razor模板引擎在Asp.net Core中封装在了MVC模块之中,需要做一些扩展才可以单独拿出来使用

创建模板页面

创建 views文件夹

$ mkdir views
$ cd views

创建 index.cshtml 页面

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<ul>
@for (int i = 0; i < 5; i++)
{
<li>第@(i + 1)行</li>
}
</ul>
</body>
</html>

使用模板

using System;
using System.IO;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection; namespace Demo
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(AppContext.BaseDirectory);
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.Build();
host.Run();
}
} class Startup
{
public void ConfigureServices(IServiceCollection services)
{
//启用Mvc
services.AddMvc(); //扩展类
services.AddSingleton<RazorViewRenderer>(); }
public void Configure(IApplicationBuilder app)
{
app.UseRouter(routes =>
{
//根路径 /
routes.MapGet("", context =>
{
return context.Render("/views/index.cshtml");
}
});
} }
}

安装相关的Nuget包

$ dotnet add package Microsoft.AspNetCore.Mvc --version 2.0.2

下载依赖项

$ dotnet restore

运行

$ dotnet run

结果

第1行
第2行
第3行
第4行
第5行

渲染数据

新增实体类 UserInfo

public class UserInfo
{
public string Name { get; set; }
public int Age { get; set; }
}

新增user.cshtml页面

@using Demo;
@model UserInfo
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<ul>
<li>姓名:@Model.Name</li>
<li>年龄:@Model.Age</li>
</ul>
</body>
</html>

更改Program.cs

app.UseRouter(routes =>
{
//根路径 /
routes.MapGet("", context =>
{
return context.Render("/views/index.cshtml");
}
routes.MapGet("/user", context =>
{
return context.Render("/views/user.cshtml", new UserInfo() { Name = "张三", Age = 18 });
});
});

运行

$ dotnet run

结果

姓名:张三
年龄:18

请求数据

QueryString

var queryCollection = context.Request.Query;
foreach (var item in queryCollection)
{
Console.WriteLine(item.Key + ":" + item.Value);
}

Form

if (context.Request.ContentType.ToLower().Contains("application/x-www-form-urlencoded")
{
var formCollection = context.Request.Form;
foreach (var item in formCollection)
{
Console.WriteLine(item.Key + ":" + item.Value);
}
}

Files

var fileCollections = context.Request.Form.Files;
var rootPath = context.RequestServices.GetService<IHostingEnvironment>().ContentRootPath;
foreach (var item in fileCollections)
{ var path = Path.Combine(rootPath,item.FileNa
using (var stream = new FileStream(path, FileMode.Create))
{
await item.CopyToAsync(stream);
}
Console.WriteLine(item.FileName + ":" + item.Length);
}

Header

var headerCollection = context.Request.Headers;
foreach (var item in headerCollection)
{
Console.WriteLine(item.Key + ":" + item.Value);
}

Body

StreamReader reader = new StreamReader(context.Request.Body);
string text = reader.ReadToEnd();

Cookies

var cookieCollection=context.Request.Cookies;
foreach (var item in cookieCollection)
{
Console.WriteLine(item.Key + ":" + item.Value);
}

错误和重定向

重定向

context.Response.Redirect("path")

状态代码页

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.IO;
using System.Text.Encodings.Web; namespace Demo
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(AppContext.BaseDirectory);
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.Build();
host.Run();
}
} class Startup
{
public void ConfigureServices(IServiceCollection services)
{
//启用路由
services.AddRouting();
services.AddMvc();
services.AddSingleton<RazorViewRenderer>(); }
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//启用状态码页
app.UseStatusCodePages(); app.UseRouter(routes =>
{
//根路径 /
routes.MapGet("", context =>
{
return context.Render("/views/index.cshtml");
}
});
} }
}

自定义状态码页

新增 404.cshtml

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h1> Oops! Page Not Found ! </h1>
</body>
</html>

配置和使用自定义的状态码页

app.UseStatusCodePagesWithRedirects("/status/{0}");

app.UseRouter(routes =>
{
//""
routes.MapGet("", context =>
{
return context.Response.WriteAsync("root path");
}); routes.MapGet("status/{code}", (request, response, routeData) =>
{
var statusCodePagesFeature = request.HttpContext.Features.Get<IStatusCodePagesFeature>();
var code = routeData.Values["code"];
if (statusCodePagesFeature != null && code!=null && code.ToString() == "404")
{
//跳转到自定义的404页面
return request.HttpContext.Render("/views/404.cshtml");
}
else
{
return response.WriteAsync(HtmlEncoder.Default.Encode("状态码:"+ routeData.Values["code"]));
}
});
});

异常错误页

开发异常页面,Asp.net Core自带

app.UseDeveloperExceptionPage();

新增测试路由,抛出空指针异常

env.EnvironmentName = EnvironmentName.Development;
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/error");
} app.UseRouter(routes =>
{
//""
routes.MapGet("", context =>
{
return context.Response.WriteAsync("root path");
} //test
routes.MapGet("test", context =>
{
throw new Exception("空指针异常!!!");
});
});

访问http://localhost:57393/test,得到下面的页面

自定义异常页面

env.EnvironmentName = EnvironmentName.Production;
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
//自定义异常错误页面
app.UseExceptionHandler("/error");
} app.UseRouter(routes =>
{
//""
routes.MapGet("", context =>
{
return context.Response.WriteAsync("root path");
} //test
routes.MapGet("test", context =>
{
throw new Exception("空指针异常!!!");
}); //自定义异常错误页面
routes.MapGet("error", context =>
{
context.Response.StatusCode = 500;
context.Response.ContentType = "text/html";
var error = context.Features.Get<IExceptionHandlerFeature>();
if (error != null)
{
return context.Response.WriteAsync("<h1>" + HtmlEncoder.Default.Encode("发生了错误: " + error.Error.Messa + "</h1>");
}
else
{
return context.Response.WriteAsync("<h1>" + HtmlEncoder.Default.Encode("Oops! 发生了错误,请联系管理员")"</h1>");
}
});
});

关于响应

会话

Session

新增登陆页面login.cshtml

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<form action="/login" method="post">
<div>
<label>用户名:</label>
<input type="text" name="UserName" />
</div>
<div>
<label>密码:</label>
<input type="password" name="PassWord" />
</div>
<div>
<input type="submit" value="登陆" />
</div>
</form>
</body>
</html>

添加并启用Session,输入用户名和密码,点击登陆,保持Session数据,登陆成功跳转到/home路由页面,访问Session数据,显示当前登陆的用户名

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.IO;
using System.Threading.Tasks; namespace Demo
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(AppContext.BaseDirectory);
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.Build();
host.Run();
}
} class Startup
{
public void ConfigureServices(IServiceCollection services)
{
//启用路由
services.AddRouting();
services.AddMvc();
services.AddSingleton<RazorViewRenderer>();
//增加Session
services.AddSession();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseDeveloperExceptionPage(); // 启用Session
app.UseSession(); app.UseRouter(routes =>
{
routes.MapGet("", (request, response, routeData) =>
{
return request.HttpContext.Render("/views/login.cshtml");
}); routes.MapGet("home", context =>
{
string userName = context.Session.GetString("userName");
if (!string.IsNullOrEmpty(userName))
{
return context.Response.WriteAsync("User:" + userName);
}
else
{
context.Response.Redirect("/");
return Task.CompletedTask;
}
}); routes.MapPost("login", context =>
{
var userName = context.Request.Form["UserName"].ToString();
var password = context.Request.Form["PassWord"].ToString();
if (userName.Equals("admin") && password.Equals("123456"))
{
context.Session.SetString("userName", password);
context.Response.Redirect("/home");
return Task.CompletedTask;
}
else
{
throw new Exception("用户名或密码错误");
}
}); });
} }
}

日志

安装Nuget包

$ dotnet add package Microsoft.Extensions.Logging --version 2.0.0
$ dotnet add package Microsoft.Extensions.Logging.Console --version 2.0.0

下载依赖项

$ dotnet restore

添加日志模块

//启用日志
services.AddLogging(builder=> {
//使用控制台日志提供程序
builder.AddConsole();
});

创建ILogger实例

var logger = context.RequestServices.GetService<ILogger<Startup>> ();
//记录日志
logger.LogInformation("before hello world");

日志分类

日志的类别,可以是任意字符串,默认是完全限定的类名,例如: Demo.Startup

日志级别

logger.LogTrace();
logger.LogDebug();
logger.LogInformation();
logger.LogWarning();
logger.LogError();
logger.LogCritical();

日志过滤

给日志分类为 Demo.Startup的日志类别限定最小的日志级别是LogLevel.Information

services.AddLogging(builder=> {
builder.AddFilter("Demo.Startup", LogLevel.Information);
builder.AddConsole();
});

访问更多关于日志类别,级别,模板,过滤,作用域的说明日志类别

配置

添加配置

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks; namespace Demo
{
class Program
{
static void Main(string[] args)
{
var configBuilder = new ConfigurationBuilder();
configBuilder.AddInMemoryCollection(new Dictionary<string, string>() {
{ "name","zhangsan"},
{ "age","18"}
});
var config = configBuilder.Build(); var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseConfiguration(config)
.UseStartup<Startup>()
.Build();
host.Run();
}
}
}

读取配置

app.UseRouter(routes =>
{
routes.MapGet("", context =>
{
var config = context.RequestServices.GetService<IConfiguration>();
string name = config["name"];
string age = config["age"];
return context.Response.WriteAsync("name:"+name+",Age:"+age);
});
});

国际化

添加依赖的Nuget包

$ dotnet add package Microsoft.Extensions.Localization --version 2.0.1

下载依赖项

$ dotnet restore

资源文件命名规则

命名规则 {分类名称}.{语言区域名称}.resx

  • 分类名称:默认的分类名称就是类型的FullName,在AssemblyName后的相对路径,比如Demo.Startup,程序集的名称Demo,就剩下了Startup
  • 语言区域名称: 语言区域名称有zh-CN,en-US,更多

特殊条件下你也可以将资源文件和类定义文件放在同一个目录,这样资源文件的分类名称就是{类名称}.{语言区域名称}.resx

添加资源文件

  • 新建 myresources文件夹
  • 新建 Startup.en-US.resx 新增项 name是sayhi,value是 HelloWorld
  • 新建 Startup.zh-CN.resx 新增项 name是sayhi,value是 世界你好

添加本地化

services.AddLocalization(options =>
options.ResourcesPath = "myresources";
});

启用本地化

var cultureList = new List<CultureInfo>() {
new CultureInfo("en-US"),
new CultureInfo("zh-CN")
};
var options = new RequestLocalizationOptions()
{
SupportedCultures = cultureList,
SupportedUICultures = cultureList,
DefaultRequestCulture = new RequestCulture("zh-CN")
};
//新建基于Query String的多语言提供程序
var provider = new QueryStringRequestCultureProvider();
provider.QueryStringKey = "culture";
provider.UIQueryStringKey = "uiculture";
//删除所有多语言提供程序
options.RequestCultureProviders.Clear();
options.RequestCultureProviders.Add(provider);

资源文件读取

var stringLocalizer = context.RequestServices.GetService<IStringLocalizer<Startup>>();
string sayhi = stringLocalizer["sayhi"];

访问 http://localhost:57393/?culture=en-US 切换为英文版本,默认的语言是中文

多语言提供程序

  • 通过Query String,[默认自带]
  • 通过Cookie,[默认自带]
  • 通过Accept-Language header,[默认自带]
  • 通过RouteData

模板格式化

string username="张三";
string localizedString = _localizer["Hello {0}!", username];
 
 
标签: asp.net core

net Core 入门实战的更多相关文章

  1. Asp.net Core 入门实战

    Asp.Net Core 是开源,跨平台,模块化,快速而简单的Web框架. Asp.net Core官网的一个合集,方便一次性Clone 目录 快速入门 安装 一个最小的应用 项目模板 路由 静态文件 ...

  2. Asp.net Core 入门实战 2.请求流程

    Asp.Net Core 是开源,跨平台,模块化,快速而简单的Web框架. Asp.net Core官网的一个源码合集,方便一次性Clone,喜欢的(Star),本系列持续更新,也可以通过我的网站访问 ...

  3. 【无私分享:ASP.NET CORE 项目实战】目录索引

    简介 首先,我们的  [无私分享:从入门到精通ASP.NET MVC]   系列已经接近尾声,希望大家在这个过程中学到了一些思路和方法,而不仅仅是源码. 因为是第一次写博客,我感觉还是比较混乱的,其中 ...

  4. 【无私分享:ASP.NET CORE 项目实战(第三章)】EntityFramework下领域驱动设计的应用

    目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 在我们 [无私分享:从入门到精通ASP.NET MVC] 系列中,我们其实也是有DDD思想的,但是没有完全的去实现,因为并不是 ...

  5. 【无私分享:ASP.NET CORE 项目实战(第二章)】添加EF上下文对象,添加接口、实现类以及无处不在的依赖注入(DI)

    目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 上一章,我们介绍了安装和新建控制器.视图,这一章我们来创建个数据模型,并且添加接口和实现类. 添加EF上下文对象 按照我们以前 ...

  6. Spark入门实战系列--10.分布式内存文件系统Tachyon介绍及安装部署

    [注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 .Tachyon介绍 1.1 Tachyon简介 随着实时计算的需求日益增多,分布式内存计算 ...

  7. Spark入门实战系列--1.Spark及其生态圈简介

    [注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 .简介 1.1 Spark简介 年6月进入Apache成为孵化项目,8个月后成为Apache ...

  8. Spark入门实战系列--4.Spark运行架构

    [注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 1. Spark运行架构 1.1 术语定义 lApplication:Spark Appli ...

  9. Spark入门实战系列--6.SparkSQL(上)--SparkSQL简介

    [注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 .SparkSQL的发展历程 1.1 Hive and Shark SparkSQL的前身是 ...

随机推荐

  1. appium 特殊操作

      一.触摸操作   1.driver.tap([坐标],持续点击时间) 除了定位到元素的点击外,也可以通过tab实现坐标的点击 driver.tap(driver.tap([(216,1776)], ...

  2. September Challenge 2017

    Little Chef and Sums 分析:水题,去维护一下前缀和以及后缀和就好,注意long long #include "iostream" #include " ...

  3. QT(1)介绍

    Qt官网 Qt官网:https://www.qt.io Qt下载:http://www.qt.io/download Qt所有下载:http://download.qt.io/archive/qt Q ...

  4. uC/OS-II源码分析(三)

    首先来了解下实时系统的基本概念: 1) 临界区,共享资源,任务(类似于进程),任务切换,任务调度,可剥夺型内核,可重入函数,动态优先级调度, 2) 如何处理优先级反转问题.这个问题描述如下:有三个任务 ...

  5. @SpringBootApplication注解分析

    首先我们分析的就是入口类Application的启动注解@SpringBootApplication,进入源码: @Target(ElementType.TYPE) @Retention(Retent ...

  6. gitea (git服务器), 修改配置,更换IP地址

    使用的gitea项目管理git 服务器 (可以不用备份项目, 通过直接修改gitea配置, 直接使用) 步骤1 可以直接访问项目, 步骤2 ,如果已有项目IP地址固定为192.168.1.x, 新的I ...

  7. 流媒体中ffmpeg 命令的使用

    在linux系统中,使用到的有关流媒体音视频流进行处理的ffmpeg 命令的常用的命令己命令对应的参数如下:记录一下: 1.分离视频音频流 ffmpeg -i input_file -vcodec c ...

  8. 滴滴Booster移动APP质量优化框架 学习之旅 二

    推荐阅读: 滴滴Booster移动App质量优化框架-学习之旅 一 Android 模块Api化演练 不一样视角的Glide剖析(一) 续写滴滴Booster移动APP质量优化框架学习之旅,上篇文章分 ...

  9. ASP.NET自定义控件组件开发

    ASP.NET的开发都是事件驱动的,现在我们就来为控件添加事件.在事件之前 对委托事件要要熟悉. 其实定义事件的步骤很简单: 1.声明一个委托. 2.定义一个携带事件信息的类. 3.定义事件 4.定义 ...

  10. 数据库路由中间件MyCat - 源代码篇(17)

    此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 调用processInsert(sc,schema,sqlType,origSQL,tableName,pr ...