.NET框架之“小马过河”

.NET框架之“小马过河”

有许多流行的 .NET框架,大家都觉得挺“重”,认为很麻烦,重量级,不如其它“轻量级”框架,从而不愿意使用。面对形形色色的框架发愁,笔者也曾发愁。但我发现只要敢于尝试,这些框架都是“纸老虎”。就像“小马过河”一样,自己尝试一下,就会发现“原来河水既不像老牛说的那样浅,也不像松鼠说的那样深。”

项目中的代码,都在 LINQPad6中运行并测试通过,也可以复制到 VisualStudio中执行。

做简单的 Http服务器很“重”

有些非常简单的 Http服务器,我看到有些 .NET开发居然也用 Node.js、 Python等语言,一问,他们会回答说“这种简单的东西,用 .NET,太重了”。殊不知其实用 .NET做起来,也很轻(甚至更轻):

// 代码不需要引入任何第三方包	
var http = new HttpListener();	
http.Prefixes.Add("http://localhost:8080/");	
http.Start();	
while (true)	
{	var ctx = await http.GetContext();	using var writer = new StreamWriter(ctx.Response.OutputStream);	writer.Write(DateTime.Now);	
}

运行效果: 640?wx_fmt=gif

可见,包括空行,仅10行代码即可完成一个简单的 HTTP服务器。

使用 EntityFramework很“重”

EntityFramework,简称 EF,现在有两个版本, EFCore和 EF6,其中 EFCore可以同时运行在 .NETFramework和 .NETCore中,但 EF6只能在 .NETFramework中运行。本文中只测试了 EFCore,但 EF6代码也一样简单。

EntityFramework是 .NET下常用的数据访问框架,以代码简单、功能强大而著名。但不少人却嗤之以鼻、不以为意。询问时,回答说 EntityFramework很“重”。

这个“重”字,我理解为它可能占用内存高,或者它可能代码极其麻烦,配置不方便(像 iBatisHibernate那样),真的这样吗?

如图,假设我有一个 UserVoiceStatus表:

640?wx_fmt=png

下面,我们通过 EF将数据取出来:

// 引用NuGet包:	
// Microsoft.EntityFrameworkCore.SqlServer	
void Main()	
{	var db = new MyDB(new DbContextOptionsBuilder()	.UseSqlServer(Util.GetPassword("ConnectionString"))	.Options);	db.UserVoiceStatus.Dump();	
}	
public class UserVoiceStatus	
{	public byte Id { get; set; }	public string Name { get; set; }	
}	
public class MyDB : DbContext	
{	public MyDB(DbContextOptions options): base(options)	{	}	public DbSet<UserVoiceStatus> UserVoiceStatus { get; set; }	
}

执行效果如图: 640?wx_fmt=png

注意,如果使用 LINQPad,事情还能更简单,只要一行代码即可,效果完全一样: UserVoiceStatuses

使用 ASP.NET MVC很“重”

上文说到了如何做一个简单的 Http服务器,如果想复杂一点,初始化 ASP.NET MVC也很简单,甚至只需要一个文件即可完成:

void Main()	
{	WebHost	.CreateDefaultBuilder()	.UseStartup<UserQuery>()	.UseUrls("https://localhost:55555")	.Build()	.Run();	
}	
public void ConfigureServices(IServiceCollection services)	
{	services.AddControllers();	
}	
public void Configure(IApplicationBuilder app)	
{	app.UseRouting();	app.UseEndpoints(endpoints =>	{	endpoints.MapControllerRoute(	name: "default",	pattern: "{controller}/{action}/{id?}",	defaults: new { controller = "Home", action = "Index" });	});	
}	
namespace Controllers	
{	public class HomeController : Controller	{	public DateTime Index()	{	return DateTime.Now;	}	}	
}

麻雀虽小,五脏俱全,这么简短的几千代码中,可以使用 Https、包含了依赖注入,还能完整的路由功能,就构成了 ASP.NET MVC的基本代码。运行效果如图: 640?wx_fmt=png

使用 WebSockets很“重”

WebSockets是个流行的 Http双向通信技术,以前在 Node.js中很流行(用 socket.io)。代码如下:

async Task Main()	
{	await WebHost	.CreateDefaultBuilder()	.UseStartup<UserQuery>()	.UseUrls("https://*:55555")	.Build()	.RunAsync();	
}	
async Task Echo(HttpContext ctx, WebSocket webSocket, CancellationToken cancellationToken)	
{	var buffer = new byte[4096];	ValueWebSocketReceiveResult result = await webSocket.ReceiveAsync(buffer.AsMemory(), cancellationToken);	while (!result.EndOfMessage)	{	await webSocket.SendAsync(buffer.AsMemory(..result.Count), result.MessageType, result.EndOfMessage, cancellationToken);	result = await webSocket.ReceiveAsync(buffer.AsMemory(), cancellationToken);	}	await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "NA", cancellationToken);	
}	
public void ConfigureServices(IServiceCollection services)	
{	
}	
public void Configure(IApplicationBuilder app)	
{	app.UseWebSockets();	app.Use(async (ctx, next) =>	{	if (ctx.Request.Path == "/ws")	{	if (ctx.WebSockets.IsWebSocketRequest)	{	WebSocket webSocket = await ctx.WebSockets.AcceptWebSocketAsync();	await Echo(ctx, webSocket, CancellationToken.None);	return;	}	}	await next();	});	app.Run(x => x.Response.WriteAsync("Please call /ws using WebSockets."));	
}

该代码是个 Echo服务器,它会将客户端发过来和内容,按原因返回给客户端。然后, .NET也内置了 WebSockets的客户端:可以高效地访问刚刚创建并运行的 WebSockets服务器。

using (var ws = new ClientWebSocket())	
{	await ws.ConnectAsync(new Uri("wss://localhost:55555/ws"), CancellationToken.None);	var completeEvent = new ManualResetEventSlim();	var cts = new CancellationTokenSource();	new Task(() => SendMessage(ws, cts)).Start();	var buffer = new byte[4096];	do	{	var r = await ws.ReceiveAsync(buffer, cts.Token);	$"[{Util.ElapsedTime}] Received {Encoding.UTF8.GetString(buffer, 0, r.Count)}".Dump();	} while (ws.State != WebSocketState.Closed);	
}	
$"[{Util.ElapsedTime}] Closed.".Dump();	
async void SendMessage(WebSocket ws, CancellationTokenSource cts)	
{	for (var i = 0; i < 3; ++i)	{	await ws.SendAsync(	Encoding.UTF8.GetBytes($"[{Util.ElapsedTime}] Send {DateTime.Now.ToString()}".Dump()),	WebSocketMessageType.Text,	endOfMessage: false, default);	await Task.Delay(1000);	}	await ws.CloseAsync(WebSocketCloseStatus.Empty, null, default);	cts.Cancel();	
}

最后,客户端与服务器双向通信效果如下: 640?wx_fmt=gif

使用 SignalR很“重”

SignalR是 ASP.NET推出的抽象式的 Http协议双向通信框架。 SignalR可以用相同的 API,支持像长轮询、 ServerSentEvents和 WebSocket的技术。 SignalR默认优先选择使用 WebSocket以达到最高性能,如果客户端或服务器不支持,则会回退至其它稍慢的技术。

SignalR客户端还支持几乎所有语言、所有平台。它是如此好用,几乎可以取代传统的请求/响应,成为新的 Http开发模型。(事实上 Blazor正在尝试这样做)

但 SignalR最为令人震撼的,还是它非常简单的使用方式,而恰恰是这一点给人误会最深。它的服务端 API,甚至比 WebSocket还要简单清晰简单:

async Task Main()	
{	await WebHost	.CreateDefaultBuilder()	.UseStartup<UserQuery>()	.UseUrls("https://localhost:55555")	.Build()	.RunAsync();	
}	
public void ConfigureServices(IServiceCollection services)	
{	services.AddSignalR();	
}	
public void Configure(IApplicationBuilder app)	
{	app.UseRouting();	app.UseEndpoints(endpoints =>	{	endpoints.MapHub<Hubs.ChatHub>("/chat");	});	
}	
namespace Hubs	
{	public class ChatHub : Hub	{	public async Task Broadcast(string id, string text)	{	await Clients.All.SendAsync("Broadcast", id, text);	}	}	
}

前文提到, SignalR提供了所有平台的 SignalR客户端,如 js、 Android等,其中当然(显然)也包括 .NET的。 SignalR的 .NET客户端使用起来也非常简单:

// 引入NuGet包:Microsoft.AspNetCore.SignalR.Client	
// 代码在LINQPad中运行	
var hub = new HubConnectionBuilder()	.WithUrl("https://localhost:55555/chat")	.Build();	
hub.On("Broadcast", (string id, string msg) =>	
{	Console.WriteLine($"{id}: {msg}");	
});	
new Label("姓名: ").Dump();	
var idBox = new TextBox(Guid.NewGuid().ToString()).Dump();	
await hub.StartAsync();	
while (true)	
{	var text = Console.ReadLine();	if (text == "Q") break;	await hub.SendAsync("Broadcast", idBox.Text, text);	
}

这是一个非常简单的多人聊天室,运行效果如下: 640?wx_fmt=gif

总结

面对形形色色的框架发愁,笔者也曾发愁。但现在不了,什么框架拿过来,马上试试,也就几十秒钟的事。好用不好用,用用便知。

那么读者,你的“小马过河”的故事是怎样的呢?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/313801.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入理解 JVM Class文件格式(三)

** JVM常量池中各数据项类型详解 ** 关于常量池的大概内容&#xff0c; 已经在 深入理解 JVM Class文件格式&#xff08;一&#xff09; 中讲解过了&#xff0c; 这篇文章中还介绍了常量池中的11种数据类型。 本文的任务是详细讲解这11种数据类型&#xff0c; 深度剖析源文件…

深入理解 JVM Class文件格式(四)

&#xff08;3&#xff09;CONSTANT_Integer_info 一个常量池中的CONSTANT_Integer_info数据项, 可以看做是CONSTANT_Integer类型的一个实例。 它存储的是源文件中出现的int型数据的值。 同样&#xff0c; 作为常量池中的一种数据类型&#xff0c; 它的第一个字节也是一个tag值…

.Net Core中使用Quartz.Net Vue开即用的UI管理

Quartz.NETQuartz.Net 定制UI维护了常用作业添加、删除、修改、停止、启动功能&#xff0c;直接使用cron表达式设置作业执行间隔&#xff0c;有完整的日志记录。Quartz.NET是一个功能齐全的开源作业调度系统&#xff0c;可用于从最小的应用程序到大型企业系统。Quartz.NET是一个…

深入理解 JVM Class文件格式(五)

&#xff08;8&#xff09; CONSTANT_Class_info 常量池中的一个CONSTANT_Class_info&#xff0c; 可以看做是CONSTANT_Class数据类型的一个实例。 他是对类或者接口的符号引用。 它描述的可以是当前类型的信息&#xff0c; 也可以描述对当前类的引用&#xff0c; 还可以描述对…

混沌工程详细介绍——Netflix持续交付实践探寻

内容来源&#xff1a;DevOps案例深度研究 – Netflix的文化与工程实践战队&#xff08;本文只展示部分案例PPT及研究成果&#xff0c;更多细节请关注案例分享活动&#xff0c;及本公众号&#xff09;。本案例内容贡献者&#xff1a;高金梅&#xff0c;李晓莉&#xff0c;潘雄鹰…

深入理解 JVM Class文件格式(六)

经过前几篇文章&#xff0c; 终于将常量池介绍完了&#xff0c; 之所以花这么大的功夫介绍常量池&#xff0c; 是因为对于理解class文件格式&#xff0c;常量池是必须要了解的&#xff0c; 因为class文件中其他地方&#xff0c;大量引用了常量池中的数据项。 对于还不了解常量池…

远程开发初探 - VS Code Remote Development

如果你是学生&#xff0c;你还在你的 windows 电脑上为各种环境配置头疼的时候&#xff0c;你应该了解一下 Remote Development。如果你喜欢 linux 的开发环境和舒适的 shell&#xff0c;但却不舍得抛弃 windows/macos 图形界面给你带来的用户体验和一些软件的兼容(QQ, 微信), …

深入理解 JVM Class文件格式(七)

本专栏列前面的一系列博客&#xff0c; 对Class文件中的一部分数据项进行了介绍。 本文将会继续介绍class文件中未讲解的信息。 先回顾一下上面一篇文章。 在上一篇博客中&#xff0c; 我们介绍了&#xff1a; this_class 对当前类的描述 super_class 对当前类的超类的描述 in…

微信小程序集成腾讯云 IM SDK

1、背景因业务功能需求需要接入IM&#xff08;即时聊天&#xff09;功能&#xff0c;一开始想到的是使用 WebSocket 来实现这个功能&#xff0c;然天意捉弄&#xff08;哈哈&#xff09;服务器版本太低不支持 wx 协议&#xff08;也就不支持 WebSocket了&#xff09;不得不寻找…

深入理解 JVM Class文件格式(八)

在本专栏的第一篇文章 深入理解Java虚拟机到底是什么 中&#xff0c; 我们主要讲解了什么是虚拟机&#xff0c; 这篇博客是对JVM的一个概述。 在随后的几篇文章中&#xff0c;一直在讲解class文件格式。 在今天这篇博客中&#xff0c; 将会继续讲解class文件中的其他信息。 在本…

深入理解 JVM Class文件格式(九)

经过前八篇关于class文件的博客&#xff0c; 关于class文件格式的内容也基本上讲完了。 本文是关于class文件格式的最后一篇。 在这篇博客中&#xff0c; 将会讲解关于方法的几个属性。 理解这篇博客的内容&#xff0c; 对于理解JVM执行引擎起着重要作用。 关于虚拟机执行引擎有…

MongoDB入门及 c# .netcore客户端MongoDB.Driver2.9.1使用

MongoDB 是一个基于分布式文件存储的数据库。由 C 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。什么场景下使用MongoDBMongoDB虽然是NoSQL(非关系型的数据库)&#xff0c;但是实际使用的时候可以当做关系型数据库来用&#xff0c;mysql等数据库中单表数据量…

《WTM送书活动:向更遥远的星辰大海起航~》

点击上方蓝字关注我们吧是的,没错~这一篇不是大老刘写的 哈哈~啥? 你想知道为啥? 大老刘为了你们不加班,熬夜改BUG,姑娘不乐意了...然后...后面请自行脑补~哎~生活还要继续鸭....那么,接下来由我陪大家唠一段儿~ 单口...各位看官老爷们:注意了!第一件事情呢我们的WTM框…

Java中的对象一定在堆上分配吗?

首先&#xff0c;为解释这个问题&#xff0c;需要的基本知识如下&#xff08;如果对以下概念不太熟悉&#xff0c; 可以先了解下&#xff09;&#xff1a; 1.JVM内存结构&#xff0c;传送门 2.即时编译&#xff08;JIT&#xff09;&#xff0c;传送门 3. 逃逸分析&#xff0c;…

最全的 netcore 3.0 升级实战方案

1、哈喽大家中秋节&#xff08;后&#xff09;好呀&#xff01;感觉已经好久没有写文章了&#xff0c;但是也没有偷懒哟&#xff0c;我的视频教程《系列一、NetCore 视频教程&#xff08;Blog.Core&#xff09;》也已经录制八期了&#xff0c;还在每周末同步更新中&#xff0c;…

微软发布.Net Core 3.0 RC1,最终版本定于9月23日

2019.9.17 微软 宣布推出.NET Core 3.0 Release Candidate 1。就像Preview 9一样&#xff0c;主要专注于为 .NET Core 3.0 发布最终版本 。现在变得非常非常接近。将在9月23日.NET Conf上发布最终版本。.NET Core 3.0是从仅支持Windows传统的 .NET框架向更现代化的开源实现过渡…

JVM内存结构 VS Java内存模型 VS Java对象模型

Java作为一种面向对象的&#xff0c;跨平台语言&#xff0c;其对象、内存等一直是比较难的知识点。而且很多概念的名称看起来又那么相似&#xff0c;很多人会傻傻分不清楚。比如本文我们要讨论的JVM内存结构、Java内存模型和Java对象模型&#xff0c;这就是三个截然不同的概念&…

迫于误解压力,RMS从自由软件基金会与MIT离职

自由软件基金会官网显示&#xff0c;基金会创始人兼主席、自由软件运动发起人 Richard M. Stallman&#xff08;RMS&#xff09;辞去主席职务并辞去董事会职务。而另一边&#xff0c;stallman.org 邮件列表显示&#xff0c;RMS 已经从麻省理工学院&#xff08;MIT&#xff09;计…

让人迷茫的三十岁!从专业技能、行业知识和软实力谈一下!

作者&#xff1a;邹溪源&#xff0c;长沙资深互联网从业者&#xff0c;架构师社区合伙人&#xff01;我今年三十岁&#xff0c;我很迷茫&#xff0c;不知道未来该选择什么发展方向。这是我无意中在社区微信群中看到的一位年轻的开发者说的话&#xff0c;之前他也经常会在技术群…

误用.Net Redis客户端工具CSRedisCore,自己挖坑自己填

前导  上次Redis MQ分布式改造完成之后&#xff0c; 编排的容器稳定运行了一个多月&#xff0c;昨天突然收到ETL端同事通知&#xff0c;没有采集到解析日志了。赶紧进服务器看了一下&#xff0c;用于数据接收的receiver容器挂掉了&#xff0c; 尝试docker container start [c…