我还没安装 VS2026 ,等到正式版推出了再说
不过 .NET LTS 的时间倒是很值得关注,三年是不是有点少?毕竟微软自家 Visual Studio 本体的支持时间远不止 3 年,如果跑在 .NET LTS 那可能真不够用
题外话:每个 IDE 厂商(尤其是 JetBrains)都应该参考一下微软的这次“营销”技巧,专门留一行字给老板和采购部门看,让他们尽量买高配电脑而不是按照最低需求来买(除非他们钻细节找到真实配置需求的网页)
]]>我搜索了一下,解决方案是:
由于本人从未接触此类开发,所以有疑问想请教大佬:
作为一个 C# 新手,完成了我的第一个真正有用的个人项目:Wallpaper Switcher (壁纸切换器),并已开源。
一句话介绍: 一个基于 WinForms 开发的轻量级工具,专注于快速、方便地管理和切换静态壁纸。支持 Windows 8/10/11 (.NET 9)。
核心痛点 & 为什么做这个?
主要功能亮点:
Native
:用系统幻灯片,流畅但间隔受限。Custom
:直接 API 调用,切换更快更即时。技术选型与开发亮点:
Core
(核心逻辑库) + Desktop
(WinForms UI) 分离。核心逻辑封装良好,为未来可能的 UI 迁移( WPF/WinUI/Avalonia )留有余地。CsWin32
(强烈推荐!):基于源生成器,自动生成精确 P/Invoke 签名,大幅简化代码(壁纸设置、热键注册、启动项管理),提升安全性和正确性。DllImport
迁移到更现代的 LibraryImport
(源生成)。获取与使用:
WallpaperSwitcher.exe
(单文件,首次运行慢) 或 WallpaperSwitcher.zip
(解压运行 bin\WallpaperSwitcher.exe
,推荐)。期待你的反馈! 作为第一个完整的 C# 实用项目,深知代码和设计必有不足。非常欢迎:
请在 GitHub Issues/PR 或 本帖回复 中提出!你的反馈是宝贵的学习机会。
希望这个小工具也能为你带来便利!
(文章用 Deepseek 进行了优化,本人文采不好,内容是自己写的只不过让 AI 润色了一下,见谅)
]]>引用三方包
#:package Humanizer@2.14.1 using Humanizer; var dotNet9Released = DateTimeOffset.Parse("2024-12-03"); var since = DateTimeOffset.Now - dotNet9Released; Console.WriteLine($"It has been {since.Humanize()} since .NET 9 was released.");
linux shebang
#!/usr/bin/dotnet run Console.WriteLine("Hello from a C# script!");
chmod +x app.cs ./app.cs
https://devblogs.microsoft.com/dotnet/announcing-dotnet-run-app
v 站的 dotnet 节点好冷清~~~
]]>WCF
,后来使用了 gRPC
后,因为不想定义 proto 文件,就在想有没有办法像用 WCF
一样使用 gRPC
,经过摸索后,就有了现在这个组件。 如果你也有和我类似的想法,欢迎试用。
地址在这里
]]>正常情况下日订单在五百万左右。这个页面需要显示每个 SKU 在不同阶段(状态)的订单的数量。有考虑过用 Redis 但是我们的 Redis 是单机的只用来缓存,经常 flushall 。再单独加一台 Redis 觉得不划算
return Ok(dbContext.Orders.Where(x => x.CreatedAt >= DateTimeOffset.FromUnixTimeMilliseconds(queryForm.StartDate) && x.CreatedAt <= DateTimeOffset.FromUnixTimeMilliseconds(queryForm.EndDate)) .Include(x => x.Sku).Where(x => x.Sku != null) .GroupBy(o => o.SkuId) .Select(g => new { SkuId = g.Key, SkuName = g.Select(o => o.Sku.TitleEng).FirstOrDefault(), Delivering = g.Count(o => o.Status == (int)OrderStatusEnum.Delivering), Cancelled = g.Count(o => o.Status == (int)OrderStatusEnum.Cancelled), InProcess = g.Count(o => o.Status == (int)OrderStatusEnum.InProcess), InReview = g.Count(o => o.ReviewTasks.Any(t => t.Pending && t.Result == false)), Total = g.Count() }) .ToList());
能想到的索引都已经加了
[Index(nameof(Status))] [Index(nameof(Input))] [Index(nameof(SkuId))] [Index(nameof(UserId))] [Index(nameof(CreatedAt))] [Index(nameof(UpdatedAt))] [Index(nameof(OrderTag))] [Index(nameof(SendPending))] [Index(nameof(OrderSource))] [Index(nameof(UserId), nameof(SkuId), nameof(FromMobileApp))] [Index(nameof(UserId), nameof(Status))] [Index(nameof(SkuId), nameof(Status))] [Index(nameof(Status), nameof(RiskyScore))] [Index(nameof(UserId), nameof(Input))] [Index(nameof(UserId), nameof(InputTailing))] public class Order : BaseEntity { ... }
]]>using System; using System.Reactive.Linq; using System.Reactive.Subjects; public class BasicMessageBus { private static readonly BasicMessageBus _instance = new(); public static BasicMessageBus Inst => _instance; private readonly Subject<object> _messages = new(); public IObservable<T> Subscribe<T>() => _messages.OfType<T>(); public void Send(object message) => _messages.OnNext(message); }
]]>在调试模式下也只有这一点错误信息,问题出在哪行代码和错误堆栈都没有打印,IDE 里也不能像桌面应用一样自动暂停下断点
]]>var ids = new List<string>() { "A001", "B001" }; appDbContext.RackTransfers.FromSql($"select * from RackTransfers where Id IN ({ids})");
]]>问题场景:我的 webapi 与 Redis 读写操作有关的 API 全部会 500
检查:Redis 服务一切正常
修复方法:清空所有缓存
无法理解的特殊现象:我有两个 webapi ,一个用的 db5 ,一个用的 db1 ,我猜测是 db5 出了问题,但是 db1 的 api 也一起挂掉了,然后我清空了 db5 ,所有服务全部正常了
下面是小弟 debug 到的一段异常,我问了 GPT ,说这是和 缓存副本
相关的异常,可是我的系统并没有做负载均衡类的部署,所以请教各位大佬,这到底是怎么造成的?
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1] An unhandled exception has occurred while executing the request. StackExchange.Redis.RedisCommandException: Command cannot be issued to a replica: DEL cache_4f4bc6e0-4278-d758-4312-3be96b11d34e at StackExchange.Redis.ConnectionMultiplexer.PrepareToPushMessageToBridge[T](Message message, ResultProcessor`1 processor, IResultBox`1 resultBox, ServerEndPoint& server) in /_/src/StackExchange.Redis/ConnectionMultiplexer.cs:line 1967 at StackExchange.Redis.ConnectionMultiplexer.TryPushMessageToBridgeAsync[T](Message message, ResultProcessor`1 processor, IResultBox`1 resultBox, ServerEndPoint& server) in /_/src/StackExchange.Redis/ConnectionMultiplexer.cs:line 2013 at StackExchange.Redis.ConnectionMultiplexer.ExecuteAsyncImpl[T](Message message, ResultProcessor`1 processor, Object state, ServerEndPoint server) in /_/src/StackExchange.Redis/ConnectionMultiplexer.cs:line 2191 at StackExchange.Redis.RedisBase.ExecuteAsync[T](Message message, ResultProcessor`1 processor, ServerEndPoint server) in /_/src/StackExchange.Redis/RedisBase.cs:line 54 at StackExchange.Redis.RedisDatabase.KeyDeleteAsync(RedisKey key, CommandFlags flags) in /_/src/StackExchange.Redis/RedisDatabase.cs:line 758 at aibotPro.Service.RedisService.DeleteAsync(String key) in /Users/mayday/Desktop/GitHub/AIBot-Pro/AIBot-Pro/aibotPro/aibotPro/Service/RedisService.cs:line 75 at aibotPro.Service.UsersService.GenerateCodeImage(String account, String key) in /Users/mayday/Desktop/GitHub/AIBot-Pro/AIBot-Pro/aibotPro/aibotPro/Service/UsersService.cs:line 151 at aibotPro.Controllers.UsersController.GenerateCodeImage(String key) in /Users/mayday/Desktop/GitHub/AIBot-Pro/AIBot-Pro/aibotPro/aibotPro/Controllers/UsersController.cs:line 388 at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope) at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger) at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task) fail: Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor[3] The view 'Error' was not found. Searched locations: /Views/Home/Error.cshtml, /Views/Shared/Error.cshtml fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[3] An exception was thrown attempting to execute the error handler. System.InvalidOperationException: The view 'Error' was not found. The following locations were searched: /Views/Home/Error.cshtml /Views/Shared/Error.cshtml at Microsoft.AspNetCore.Mvc.ViewEngines.ViewEngineResult.EnsureSuccessful(IEnumerable`1 originalLocations) at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor.ExecuteAsync(ActionContext context, ViewResult result) at Microsoft.AspNetCore.Mvc.ViewResult.ExecuteResultAsync(ActionContext context) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|30_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope) at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger) at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.HandleException(HttpContext context, ExceptionDispatchInfo edi)
]]>我之前使用 VS code 时是单独从微软网站上下载安装.Net 8.0 。安装以后运行 dotnet --info ,Host:Version: 当时显示的是 8.0 。 请问我如何才能将.Net 版本升级到 8.0 呢?
global.json file: Not found Host: Version: 6.0.31 Architecture: x64 Commit: e2ca2f8a1c .NET SDKs installed: No SDKs were found. .NET runtimes installed: Microsoft.AspNetCore.App 8.0.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 6.0.31 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 8.0.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 6.0.31 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 8.0.6 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Download .NET: https://aka.ms/dotnet-download Learn about .NET Runtimes and SDKs: https://aka.ms/dotnet/runtimes-sdk-info
]]>1 、网页说:更新 global.json 文件。但是没有说这个文件在哪里?我在 CMD 中输入 dotnet --info 输出信息中提示
Environment variables: Not set
global.json file: Not found
我问 gpt ,它说“如果项目根目录下没有 global.json 文件,你可以手动创建一个:”-------------问题是我有很多项目。难道每个项目下面都要新建一个 global.json 文件。那工作量可有点大!
2 、网页上说:“更新目标框架将项目文件的目标框架名字对象 (TFM) 更新为 net8.0:”
----我对这句话的理解是更新项目下的 project 文件。也就是.csproj 文件。可是每个项目下都有好多.csproj 文件。难道都要更新?
gpt 的回答是“确实,对于包含多个项目的解决方案,逐个手动更新每个项目的 .csproj 文件工作量较大。不过,可以通过编写脚本来批量更新这些文件,从而减少手动操作的工作量。以下是几种解决方案,可以帮助你简化这个过程:”
-----gpt 的回答不敢全信。以上升级过程存在很多疑问和不确定性。请问各位老师是否有具体的指导或者更简单升级方法。或者有相关详细升级步骤的视频分享么?如果我将当前的 7.0 彻底卸载,重新安装 8.0 是否会导致当前 build 的项目全都不可用,需要重新 build 。或者我还是要手动逐个更新 vscode 中的 solution 和 project 文件?
]]>开始使用的时候用 c# for vscode,VSCode-solution-explorer,nuget package manager,C# XML Documentation Comments 等插件配合起来开发 dotnet6. 后来微软推出的 c# for vscode + c# dev kit 不断的升级,基本上取代了之前用的那些插件。 visual studio for MAC 上,微软后期也不在继续更新,这就意味着其他平台上.NET 开发工具的主力就会是 vscode 。 开始使用的时候先尝试了直接使用 dotnet cli 的一些基本命令,来管理项目和解决方案。
dotnet new sln -o solution // 新建解决方案 dotnet new list //列出 templates dotnet new console -n conApp // 新建一个控制台程序 dotnet new classlib -n Lib -f net6.0 // 新建类库 dotnet sln add .\Lib\Lib.csproj 加入到解决方案
dotnet nuget
dotnet nuget list source dotnet nuget add source 添加源 dotnet nuget remove source dotnet disable source dotnet enable source
当然我们经常用过命令来管理项目确实有写麻烦。 c# kit dev 给 dotnet 开发者提供了 solution explorer 。
"editor.cursorBlinking": "smooth"
目前 c# dev kit 还有一些存在的问题待修复。 比如我常用到 xunit 框架用来输出日志的 output ,还无法输出到控制台,无法看到自己打印的信息。 相关 issue. No output recorded after unit testing using xUnit 为了对代码进行测试覆盖,需要安装几个插件 首先代码中需要引入 Coverlet
dotnet add package coverlet.collector
xunit 项目中使用
dotnet test --collect:"XPlat Code Coverage"
这个命令可以配置过滤条件排除一些不想被统计的代码参考文档 需要添加一个配置文件 coverlet.runsettings
<?xml version="1.0" encoding="utf-8" ?> <RunSettings> <DataCollectionRunSettings> <DataCollectors> <DataCollector friendlyName="XPlat code coverage"> <Configuration> <Format>json,cobertura,lcov,teamcity,opencover</Format> <Exclude>[coverlet.*.tests?]*,[*]Coverlet.Core*</Exclude> <!-- [Assembly-Filter]Type-Filter --> <Include>[coverlet.*]*,[*]Coverlet.Core*</Include> <!-- [Assembly-Filter]Type-Filter --> <ExcludeByAttribute>Obsolete,GeneratedCodeAttribute,CompilerGeneratedAttribute</ExcludeByAttribute> <ExcludeByFile>**/dir1/class1.cs,**/dir2/*.cs,**/dir3/**/*.cs,</ExcludeByFile> <!-- Globbing filter --> <IncludeDirectory>../dir1/,../dir2/,</IncludeDirectory> <SingleHit>false</SingleHit> <UseSourceLink>true</UseSourceLink> <IncludeTestAssembly>true</IncludeTestAssembly> <SkipAutoProps>true</SkipAutoProps> <DeterministicReport>false</DeterministicReport> <ExcludeAssembliesWithoutSources>MissingAll,MissingAny,None</ExcludeAssembliesWithoutSources> </Configuration> </DataCollector> </DataCollectors> </DataCollectionRunSettings> </RunSettings>
https://github.com/coverlet-coverage/coverlet/blob/master/Documentation/VSTestIntegration.md 为了在 vscode 中可以展示对应文件的代码覆盖率,可以使用这个插件 Coverage Gutters https://marketplace.visualstudio.com/items?itemName=ryanluker.vscode-coverage-gutters 为了生成对那个的代码测试报告,可以安装 RepotGenerator
** tasks.json **
[ { "command": "dotnet", "args": [ "build", "${workspaceFolder}\\xxx.csproj", "/property:GenerateFullPaths=true", "/consoleloggerparameters:NoSummary" ], "problemMatcher": "$msCompile", "type": "process", "label": "dotnet: build APIGateway4" } ]
** launch.json **
[{ "name": ".NET8 Launch (APIGateway4)", "type": "coreclr", "request": "launch", "preLaunchTask": "dotnet: build APIGateway4", "program": "${workspaceFolder}\\APIGateway4.exe", "args": [], "cwd": "${workspaceFolder}\\src\\APIGateway\\APIGateway4", "stopAtEntry": false, "serverReadyAction": { "action": "openExternally", "pattern": "\\bNow listening on:\\s+( https?://\\S+)" }, "env": { "ASPNETCORE_ENVIRONMENT": "Development" } }], "compounds": [ { "name": ".NET8 Launch (ALL API Gateway)", "configurations": [ ".NET8 Launch (APIGateway)", ".NET8 Launch (APIGateway2)" ], "stopAll": false } ]
"editor.guides.bracketPairs": "active", "editor.bracketPairColorization.enabled": true,
按 Ctrl + , 打开 VS Code setting ,搜索 terminal profiles windows,或者 ctrl + shift +p 打开 vs code Command Pallet 搜索 编辑 settings.json
"terminal.integrated.defaultProfile.windows": "Cmder", "terminal.integrated.profiles.windows": { "Cmder": { "name": "Cmder", "path": [ "${env:windir}\\Sysnative\\cmd.exe", "${env:windir}\\System32\\cmd.exe" ], "args": ["/k", "${env:cmder_root}\\vendor\\bin\\vscode_init.cmd"], "icon": "terminal-cmd", "color": "terminal.ansiGreen" }, },
需要提前配置一下环境变量 CMDER_ROOT 指向 Cmder 的安装目录
Quick fix 失效了
quick fix 按 ctrl + . 失效了,可以尝试修改成其他的快捷键 shift + ctrl + p 输入 Open Keyboard Shortcuts search quick fix 比如修改成 ctrl + shift + .
总体感觉 vscode ,在微软更新了 c# + c# dev kit 之后,写 dotnet 的代码体验越来越好,给我的感觉是轻量和可定制化,希望 vscode for dotnet 越来越好。 ** 那么你有没有在使用 vscode 来开发 dotnet 呢? 可以与我一起讨论这个话题 **
]]>目前我的设计是一个独立 ASP.Net Core 程序接受数据存入数据库(因为有在线率要求,处理任务的程序需要经常重启更新,有的时候会更新坏掉),另一个程序每 2 秒查询一次数据库的新数据,按需要上报的上游分类好进入 5 个不同队列(不能接受数据的时候就分类,因为分类的逻辑也要经常改),另外启动的时候开 5 个线程在数据库里扫描这些队列,发现新的任务就开一个异步 Task 上报。不同上游能接受的并发不一样,Task 外面有个 semaphoreSlim.WaitAsync();
防止把上游服务弄炸。这种实现 CPU 占用率很高,4C8G 阿 里 云占用一直在 100%,有没有人知道最佳实现是什么?
尝试: 1 、在添加了一些代码后,我自己在本地上运行可以获取到,但是发布到 IIS 上无法获取 2 、后来又按照微软官方文档尝试在 Program.cs 中添加一些代码后,在打开这个统一 Web 网页的时候需要使用域账户密码登录,登陆后的确能获取到域账户名称。
求助:现在就是想,有没有一个办法可以不登录窗口从而进入网页直接获取当前域账户名,请各位大佬指点 之前没弄过 asp.net ,感觉无从下手
]]>主要更新:
.NET 运行时和基础库: https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-8
ASP.NET Core (Web 开发): https://learn.microsoft.com/en-us/aspnet/core/release-notes/aspnetcore-8.0
Entity Framework Core (ORM): https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-8.0/whatsnew
MAUI (跨平台 UI): https://learn.microsoft.com/en-us/dotnet/maui/whats-new/dotnet-8
C#: https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-12
F#: (更新日志还没发于是先放个 blog) https://devblogs.microsoft.com/dotnet/announcing-fsharp-8
官方 Blog 介绍:
.NET 8: https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-8
ASP.NET Core 8: https://devblogs.microsoft.com/dotnet/announcing-asp-net-core-in-dotnet-8
Entity Framework Core 8: https://devblogs.microsoft.com/dotnet/announcing-ef8
Aspire (云原生开发): https://devblogs.microsoft.com/dotnet/introducing-dotnet-aspire-simplifying-cloud-native-development-with-dotnet-8
C# 12: https://devblogs.microsoft.com/dotnet/announcing-csharp-12
F# 8: https://devblogs.microsoft.com/dotnet/announcing-fsharp-8
MAUI: https://devblogs.microsoft.com/dotnet/announcing-dotnet-maui-in-dotnet-8
性能改进:
https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-8
https://devblogs.microsoft.com/dotnet/this-arm64-performance-in-dotnet-8
https://devblogs.microsoft.com/dotnet/dotnet-8-performance-improvements-in-dotnet-maui
]]>说的就是你, serilog, asyncex.
一个简单的工具类 tools, string 相关的起一个项目, int 相关的起一个项目, long 相关的起一个项目, 然后一股脑上传到 nuget 上面, 你想引入 tools, 瞬间就给你带入 toos.string, tools.int, tools.long, tools.double, tools.float, tools.bool, tools.common, tools.context.
总之一句话, 不用 dll 文件把你的 publish 文件夹塞爆绝不罢休.
它明明可以用一个 30kb 的 tools.dll, 它不, 它非要拆成 10 个 3kb 的 dll
如果依赖的三方库稍微多一点, 那最后发布文件夹简直就跟 node_modules 一样臃肿.
我觉着再这么下去, 总有一天发布文件夹内的文件会成千上万甚至几十万.
]]>