<track id="tdjf5"><big id="tdjf5"><th id="tdjf5"></th></big></track>
<th id="tdjf5"><big id="tdjf5"><nobr id="tdjf5"></nobr></big></th>
          <video id="tdjf5"><big id="tdjf5"><th id="tdjf5"></th></big></video>
            <video id="tdjf5"></video><track id="tdjf5"></track><th id="tdjf5"></th>
            <th id="tdjf5"><big id="tdjf5"></big></th>
            <video id="tdjf5"></video>
            <track id="tdjf5"></track>
            <track id="tdjf5"></track>

              .NET框架之“小馬過河”

              來源:互聯網   閱讀:-

              企業
              2020
              03/29
              09:39

              .NET框架之“小馬過河”

              有許多流行的 .NET框架,大家都覺得挺“重”,認為很麻煩,重量級,不如其它“輕量級”框架,從而不愿意使用。面對形形色色的框架發愁,筆者也曾發愁。但我發現只要敢于嘗試,這些框架都是“紙老虎”。就像“小馬過河”一樣,自己嘗試一下,就會發現“原來河水既不像老牛說的那樣淺,也不像松鼠說的那樣深?!?/p>

              項目中的代碼,都在 LINQPad6中運行并測試通過,也可以復制到VisualStudio中執行。

              做簡單的 Http服務器很“重”

              有些非常簡單的 Http服務器,我看到有些.NET開發居然也用Node.js、Python等語言,一問,他們會回答說“這種簡單的東西,用.NET,太重了”。殊不知其實用.NET做起來,也很輕(甚至更輕):

              1. // 代碼不需要引入任何第三方包

              2. var http = new HttpListener;

              3. http.Prefixes.Add("http://localhost:8080/");

              4. http.Start;


              5. while (true)

              6. {

              7. var ctx = await http.GetContext;

              8. using var writer = new StreamWriter(ctx.Response.OutputStream);

              9. writer.Write(DateTime.Now);

              10. }

              運行效果:

              可見,包括空行,僅10行代碼即可完成一個簡單的 HTTP服務器。

              使用 EntityFramework很“重”

              EntityFramework,簡稱EF,現在有兩個版本,EFCoreEF6,其中EFCore可以同時運行在.NETFramework.NETCore中,但EF6只能在.NETFramework中運行。本文中只測試了EFCore,但EF6代碼也一樣簡單。

              EntityFramework.NET下常用的數據訪問框架,以代碼簡單、功能強大而著名。但不少人卻嗤之以鼻、不以為意。詢問時,回答說EntityFramework很“重”。

              這個“重”字,我理解為它可能占用內存高,或者它可能代碼極其麻煩,配置不方便(像iBatis/Hibernate那樣),真的這樣嗎?

              如圖,假設我有一個 UserVoiceStatus表:

              下面,我們通過 EF將數據取出來:

              1. // 引用NuGet包:

              2. // Microsoft.EntityFrameworkCore.SqlServer

              3. void Main

              4. {

              5. var db = new MyDB(new DbContextOptionsBuilder

              6. .UseSqlServer(Util.GetPassword("ConnectionString"))

              7. .Options);

              8. db.UserVoiceStatus.Dump;

              9. }


              10. public class UserVoiceStatus

              11. {

              12. public byte Id { get; set; }

              13. public string Name { get; set; }

              14. }


              15. public class MyDB : DbContext

              16. {

              17. public MyDB(DbContextOptions options): base(options)

              18. {

              19. }


              20. public DbSet&lt;UserVoiceStatus&gt; UserVoiceStatus { get; set; }

              21. }

              執行效果如圖:

              注意,如果使用 LINQPad,事情還能更簡單,只要一行代碼即可,效果完全一樣:UserVoiceStatuses

              使用 ASP.NET MVC很“重”

              上文說到了如何做一個簡單的 Http服務器,如果想復雜一點,初始化ASP.NET MVC也很簡單,甚至只需要一個文件即可完成:

              1. void Main

              2. {

              3. WebHost

              4. .CreateDefaultBuilder

              5. .UseStartup&lt;UserQuery&gt;

              6. .UseUrls("https://localhost:55555")

              7. .Build

              8. .Run;

              9. }


              10. public void ConfigureServices(IServiceCollection services)

              11. {

              12. services.AddControllers;

              13. }


              14. public void Configure(IApplicationBuilder app)

              15. {

              16. app.UseRouting;

              17. app.UseEndpoints(endpoints =&gt;

              18. {

              19. endpoints.MapControllerRoute(

              20. name: "default",

              21. pattern: "{controller}/{action}/{id?}",

              22. defaults: new { controller = "Home", action = "Index" });

              23. });

              24. }


              25. namespace Controllers

              26. {

              27. public class HomeController : Controller

              28. {

              29. public DateTime Index

              30. {

              31. return DateTime.Now;

              32. }

              33. }

              34. }

              麻雀雖小,五臟俱全,這么簡短的幾千代碼中,可以使用 Https、包含了依賴注入,還能完整的路由功能,就構成了ASP.NET MVC的基本代碼。運行效果如圖:

              使用 WebSockets很“重”

              WebSockets是個流行的Http雙向通信技術,以前在Node.js中很流行(用socket.io)。代碼如下:

              1. async Task Main

              2. {

              3. await WebHost

              4. .CreateDefaultBuilder

              5. .UseStartup&lt;UserQuery&gt;

              6. .UseUrls("https://*:55555")

              7. .Build

              8. .RunAsync;

              9. }


              10. async Task Echo(HttpContext ctx, WebSocket webSocket, CancellationToken cancellationToken)

              11. {

              12. var buffer = new byte[4096];

              13. ValueWebSocketReceiveResult result = await webSocket.ReceiveAsync(buffer.AsMemory, cancellationToken);

              14. while (!result.EndOfMessage)

              15. {

              16. await webSocket.SendAsync(buffer.AsMemory(..result.Count), result.MessageType, result.EndOfMessage, cancellationToken);

              17. result = await webSocket.ReceiveAsync(buffer.AsMemory, cancellationToken);

              18. }

              19. await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "NA", cancellationToken);

              20. }


              21. public void ConfigureServices(IServiceCollection services)

              22. {

              23. }


              24. public void Configure(IApplicationBuilder app)

              25. {

              26. app.UseWebSockets;

              27. app.Use(async (ctx, next) =&gt;

              28. {

              29. if (ctx.Request.Path == "/ws")

              30. {

              31. if (ctx.WebSockets.IsWebSocketRequest)

              32. {

              33. WebSocket webSocket = await ctx.WebSockets.AcceptWebSocketAsync;

              34. await Echo(ctx, webSocket, CancellationToken.None);

              35. return;

              36. }

              37. }

              38. await next;

              39. });

              40. app.Run(x =&gt; x.Response.WriteAsync("Please call /ws using WebSockets."));

              41. }

              該代碼是個 Echo服務器,它會將客戶端發過來和內容,按原因返回給客戶端。然后,.NET也內置了WebSockets的客戶端:可以高效地訪問剛剛創建并運行的WebSockets服務器。

              1. using (var ws = new ClientWebSocket)

              2. {

              3. await ws.ConnectAsync(new Uri("wss://localhost:55555/ws"), CancellationToken.None);

              4. var completeEvent = new ManualResetEventSlim;

              5. var cts = new CancellationTokenSource;

              6. new Task( =&gt; SendMessage(ws, cts)).Start;


              7. var buffer = new byte[4096];

              8. do

              9. {

              10. var r = await ws.ReceiveAsync(buffer, cts.Token);

              11. $"[{Util.ElapsedTime}] Received {Encoding.UTF8.GetString(buffer, 0, r.Count)}".Dump;

              12. } while (ws.State != WebSocketState.Closed);

              13. }

              14. $"[{Util.ElapsedTime}] Closed.".Dump;


              15. async void SendMessage(WebSocket ws, CancellationTokenSource cts)

              16. {

              17. for (var i = 0; i &lt;3; ++i)

              18. {

              19. await ws.SendAsync(

              20. Encoding.UTF8.GetBytes($"[{Util.ElapsedTime}] Send {DateTime.Now.ToString}".Dump),

              21. WebSocketMessageType.Text,

              22. endOfMessage: false, default);

              23. await Task.Delay(1000);

              24. }

              25. await ws.CloseAsync(WebSocketCloseStatus.Empty, , default);

              26. cts.Cancel;

              27. }

              最后,客戶端與服務器雙向通信效果如下:

              使用 SignalR很“重”

              SignalRASP.NET推出的抽象式的Http協議雙向通信框架。SignalR可以用相同的API,支持像長輪詢、ServerSentEventsWebSocket的技術。SignalR默認優先選擇使用WebSocket以達到最高性能,如果客戶端或服務器不支持,則會回退至其它稍慢的技術。

              SignalR客戶端還支持幾乎所有語言、所有平臺。它是如此好用,幾乎可以取代傳統的請求/響應,成為新的Http開發模型。(事實上Blazor正在嘗試這樣做)

              SignalR最為令人震撼的,還是它非常簡單的使用方式,而恰恰是這一點給人誤會最深。它的服務端API,甚至比WebSocket還要簡單清晰簡單:

              1. async Task Main

              2. {

              3. await WebHost

              4. .CreateDefaultBuilder

              5. .UseStartup&lt;UserQuery&gt;

              6. .UseUrls("https://localhost:55555")

              7. .Build

              8. .RunAsync;

              9. }


              10. public void ConfigureServices(IServiceCollection services)

              11. {

              12. services.AddSignalR;

              13. }


              14. public void Configure(IApplicationBuilder app)

              15. {

              16. app.UseRouting;

              17. app.UseEndpoints(endpoints =&gt;

              18. {

              19. endpoints.MapHub&lt;Hubs.ChatHub&gt;("/chat");

              20. });

              21. }


              22. namespace Hubs

              23. {

              24. public class ChatHub : Hub

              25. {

              26. public async Task Broadcast(string id, string text)

              27. {

              28. await Clients.All.SendAsync("Broadcast", id, text);

              29. }

              30. }

              31. }

              前文提到, SignalR提供了所有平臺的SignalR客戶端,如js、Android等,其中當然(顯然)也包括.NET的。SignalR.NET客戶端使用起來也非常簡單:

              1. // 引入NuGet包:Microsoft.AspNetCore.SignalR.Client

              2. // 代碼在LINQPad中運行

              3. var hub = new HubConnectionBuilder

              4. .WithUrl("https://localhost:55555/chat")

              5. .Build;


              6. hub.On("Broadcast", (string id, string msg) =&gt;

              7. {

              8. Console.WriteLine($"{id}: {msg}");

              9. });


              10. new Label("姓名: ").Dump;

              11. var idBox = new TextBox(Guid.NewGuid.ToString).Dump;

              12. await hub.StartAsync;

              13. while (true)

              14. {

              15. var text = Console.ReadLine;

              16. if (text == "Q") break;

              17. await hub.SendAsync("Broadcast", idBox.Text, text);

              18. }

              這是一個非常簡單的多人聊天室,運行效果如下:

              總結

              面對形形色色的框架發愁,筆者也曾發愁。但現在不了,什么框架拿過來,馬上試試,也就幾十秒鐘的事。好用不好用,用用便知。

              那么讀者,你的“小馬過河”的故事是怎樣的呢?

              推薦閱讀:蘋果8p屏幕材質

               

              THE END
              本文系轉載,版權歸原作者所有;旨在傳遞信息,不代表烏魯木齊熱線的觀點和立場。

              相關熱點

              中文字幕无码一区二区三区亚洲|韩国三级在线 中文字幕 无码|亚洲色图无码视频深夜福利|一本岛中文免费线观看