最近每天忙着跑很多地方,回家就不想动了,没什么心情写东西。今天有空,稍微写一点。
下文中:
- 关于C语法特性的部分需要Visual Studio 2019支持。
- 关于.NET Core的部分需要安装.NET 3.0 Preview4,低版本或许也可以但我没实验。
- 如果要在最新版的VS2019中使用.NET 3.0,可能需要在
选项
–解决方案与项目
–ASP.NET Core
中启用 使用.NET Core SDK
预览版 选项。
【C 8.0新特性:可空的引用类型】
staticvoidMain(string[]args){nullableenablestringa=null;string?b=null;varc=a.Length;vard=b.Length;vare=b!.Length;nullabledisablestring?f=null;}
复制以上简单的代码到IDE就能展现这个特性的特点与用法:
- IDE会对
a
赋值为null
的操作进行警告, 因为在约定中a
不可为空,而b
则不会警告,因为它可以为null
; - IDE会对
a.Length
的访问进行警告,因为已经静态推断出a
为null
了; - IDE会对
b.Length
的访问进行警告,b
类型可能为空; b!.Length
的访问操作不会被警告,因为这种形式的访问表示老子已经知道它可能为null
了你闭嘴;string? f =null
语句会被IDE警告,因为上面已经把可为空的引用类型特性关闭了。
另外此特性不止支持enable
和disable
选项,还支持restore
还原之前的设置,以及通过safeonly
或warnings
设置定制启用警告的范围,具体可参照其详细说明。
我们可以发现这个特性的的实质其实是一个柔性断言,启用后IDE会对部分代码进行警告提示,督促我们进行处理,但也止于此了。它非常灵活,新项目启用此特性是值得的,但旧项目也没必要升级。
【C 8.0新特性:using 声明】
这里可以直接看官网的例子:
staticvoidWriteLinesToFile(IEnumerable<string>lines){usingvarfile=newSystem.IO.StreamWriter("WriteLines2.txt");foreach(stringlineinlines){// If the line doesnt contain the word Second, write the line to the file.if(!line.Contains("Second")){file.WriteLine(line);}}// file is disposed here}
等价于:
staticvoidWriteLinesToFile(IEnumerable<string>lines){using(varfile=newSystem.IO.StreamWriter("WriteLines2.txt")){foreach(stringlineinlines){// If the line doesnt contain the word Second, write the line to the file.if(!line.Contains("Second")){file.WriteLine(line);}}}// file is disposed here}
也就是说使用using
关键字修饰的变量声明,它在作用域结束后会自动释放。一开始我没明白这个有什么意义,今天和
IDispose
接口,可能是基于对语义或设计实现上的软需求,并非它一定需要调用Dispose
方法才能够释放(比如ProcessModule Class (System.Diagnostics))。在这种情况下,对于我这样的强迫症患者而言,明知道没必要,但也得不厌其烦地try finally
或者using{}
。有了这个特性,在写类似的代码的时候,可以只多加几个字就让心情舒畅,是强迫症患者的福音。另外在进行一些很常见的操作比如IO(Stream)、摘要计算(HashAlgorithm)时,可以少写一些代码。
【ASP dot NET Core 3.0中的 gRPC 服务】
.NET CORE使用gRPC服务需要用到两个Nuget包:
- 运行时:Google.Protobuf
- 支持套件:Grpc.Tools
对于客户端而言,还需要Grpc.Core包的支持。
Google.Protobuf不必解释,Grpc.Core是一系列客户端要用到的API,而Grpc.Tools的牛逼之处在于不用编译 *.proto 文件即可直接在C中引用它……
对于.NET Core 2.1 或 2.2而言使用 gPRC 服务还需要手写微量代码(XXX.BindService方法),而到了.NET CORE 3.0,引用Grpc.AspNetCore.Server包后即可直接以惯常的配置方式(AddXXX)直接使用此服务。
这里偷个懒,直接用 Visual Studio 2019+.NET CORE 3.0做示例。VS 2019中有 gRPC 服务器的模板,选择后直接会创建一个现成的新手示例。
我们一定会注意到Startup
类中ConfigureServices
方法的语句services.AddGrpc()
。这个是惯例,不用去管,重点看Configure
方法里的代码片段:
app.UseRouting();app.UseEndpoints(endpoints=>{endpoints.MapGrpcService<GreeterService>();});
此处和WCF的思想类似,将服务添加到路由终结点,让客户端连接。
然后可以看位于Protos
文件夹下的greet.proto
文件:
syntax="proto3";packageGreet;// The greeting service definition.serviceGreeter{// Sends a greetingrpcSayHello(HelloRequest)returns(HelloReply){}}// The request message containing the users name.messageHelloRequest{stringname=1;}// The response message containing the greetings.messageHelloReply{stringmessage=1;}
一个最简单的rpc服务器。
然后再看Services
文件夹下的GreeterService.cs
文件:
usingSystem.Threading.Tasks;usingGreet;usingGrpc.Core;namespaceGrpcService{publicclassGreeterService:Greeter.GreeterBase{publicoverrideTask<HelloReply>SayHello(HelloRequestrequest,ServerCallContextcontext){returnTask.FromResult(newHelloReply{Message=$"Hello { context.Method} "+request.Name});}}}
代码的实现思路很好理解。我们可以注意到我们能够直接导入Greet
命名空间,这是因为它已经被Grpc.Tools
生成到了项目下obj
文件夹的项目缓存中。
最后的一个重点在项目配置文件(*.csproj)中的ItemGroup
节点:
Include="Protos\greet.proto"GrpcServices="Server"Generator="MSBuild:Compile"/>
这就是在项目中引用proto文件的方法,具体细节详见官方说明:gRPC services with C。
然后我们可以创建个客户端尝试与服务端通讯,建立一个命令行程序,引用Google.Protobuf、Grpc.Tools以及Grpc.Core包,同时在项目配置文件中的ItemGroup
节点中加入一句话:
Include="..\GrpcService\Protos\greet.proto"GrpcServices="Client"/>
(我是在服务端项目同目录建立的客户端项目,所以路径直接这么写就OK)
然后我们可以直接写:
usingSystem;usingSystem.Threading.Tasks;usingGreet;usingGrpc.Core;namespaceConsoleApp1{classProgram{staticasyncTaskMain(string[]args){varchannel=newChannel("localhost:50051",ChannelCredentials.Insecure);varclient=newGreeter.GreeterClient(channel);varreply=awaitclient.SayHelloAsync(newHelloRequest{Name="GreeterClient"});Console.WriteLine("Greeting: "+reply.Message);awaitchannel.ShutdownAsync();Console.WriteLine("Press any key to exit...");Console.ReadKey();}}}
创建频道——创建连接——发送请求——关闭频道,简单易懂。我们着重看两点。
其一是await channel.ShutdownAsync();
:
在程序退出前,最好或者说必须关闭曾经创建过的频道。
另一个就是我们会注意到此处代码中的Greeter
类所公开的接口完全是面向客户端的。而同理,上面服务器中的Greeter
类公开的接口则是面向服务器的,这是受项目配置中GrpcServices=Client|Server
的影响,非常智能化……
声明:本文部分素材转载自互联网,如有侵权立即删除 。
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
8. 精力有限,不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别
丞旭猿论坛
暂无评论内容