HueiFeng

Microsoft MVP

All Posts


Magicodes.IE.IO:零依赖、流式低分配的 .NET Excel 读写库

Magicodes.IE.IO:零依赖、流式低分配的 .NET Excel 读写库 目录 为什么又造一个 Excel 库? 核心设计哲学 五分钟上手 与其他 Excel 库的对比 高级功能速览 与老 Magicodes.IE.Excel 的区别 AOT / NativeAOT 支持 迁移指南 总结 为什么又造一个 Excel 库? .NET 生态里的 Excel 读写方案不少——EPPlus、ClosedXML、MiniExcel、NPOI,都是成熟的好库,各有各的适用场景。但对于类库作者来说,选哪个就意味着把它的依赖链带进你的项目。EPPlus 和 ClosedXML 各自拖着一串 NuGet 包——每多一个依赖就多一份升级负担、多一个版本冲突风险。 Magicodes.IE 团队在维护老 Magicodes.IE.Excel(基于 EPPlus)的过程中吃够了这个苦,于是从头实现了一个 …


把 Kubernetes 的调度思想带入 .NET:开源分布式任务框架 KubeJob 正式发布!

背景与痛点:我们为什么又造了一个“轮子”? 在 .NET 生态中,提到后台任务调度,我们通常会想到 Quartz.NET、Hangfire 或者是 ASP.NET Core 自带的 BackgroundService。它们都非常优秀,但在现代云原生和微服务架构下,我们有时会面临一些新的挑战: 原生定时器的局限:简单的 Timer 或 IHostedService 缺乏分布式协调能力,多实例部署时容易导致任务重复执行,且没有可视化界面监控状态。 传统框架的厚重:某些成熟的调度框架与特定存储或设计模式深度绑定,对于只需要轻量级分布式调度和可视化管理的团队来说,接入成本较高。 缺乏现代化的调度策略:在集群环境中,我们往往希望任务能像 Kubernetes 调度 Pod 一样,具有“节点标签选择 (Node Selector)”、“广播执行 (Broadcast)”、“分片执行 (Sharded) …

.NET Job

.NET解决方案格式升级:SLN与SLNX

在.NET开发中,解决方案文件(.sln)长期扮演着工程管理的核心角色。但随着项目复杂度提升,传统文本格式的局限性逐渐显现。微软推出的新一代SLNX格式,以XML为基础重构了解决方案的表示方式,我们通过一个简单示例观察其改进。 原‌Sln 以下是一个包含一个csproj的传统解决方案文件片段: Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.14.35906.104 d17.14 MinimumVisualStudioVersion = 10.0.40219.1 Project({FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}) = ConsoleApp1, ConsoleApp1\ …


Visual Studio项目文件中的SCC配置属性

Visual Studio 项目文件 SCC 属性配置指南 一、SCC 属性概述 在传统的 .csproj/.vbproj 项目文件中,<PropertyGroup Label="Globals"> 节点下的 ‌SCC 属性‌用于定义项目与源代码控制系统(如 TFS、SVN、VSS 等)的集成配置。这些属性常见于旧版 Visual Studio(2010-2017)创建的项目,对团队协作开发至关重要。 二、核心属性详解 1. <SccProjectName> ▫️ 作用 定义项目在源代码控制系统中的‌唯一标识名称‌,对应服务端存储路径的映射标识。 ▫️ 典型值 SccProjectNameMyProject/Trunk/Source/SccProjectName 当值为 SAK(Should Already Know)时,表示 IDE 应自动识别绑定关系。 2. <SccProvider> …

.NET

理解并掌握C#的Channel:从使用案例到源码解读(一)

引言 在C#的并发编程中,Channel是一种非常强大的数据结构,用于在生产者和消费者之间进行通信。本文将首先通过一个实际的使用案例,介绍如何在C#中使用Channel,然后深入到Channel的源码中,解析其内部的实现机制。 使用案例一:文件遍历和过滤 在我们的使用案例中,我们需要遍历一个文件夹及其所有子文件夹,并过滤出具有特定扩展名的文件。在此,我们使用了C#的Channel来实现这个任务。 首先,我们创建了一个名为EnumerateFilesRecursively的方法,这个方法接受一个文件夹路径作为参数,并返回一个ChannelReader<string>。这个方法中,我们创建了一个有界的Channel,然后在一个单独的任务中遍历指定的文件夹及其所有子文件夹,并将找到的每个文件的路径写入Channel。当遍历完成后,我们关闭Channel的写入端。 …

.NET Channel

.NET对象的内存布局

在.NET中,理解对象的内存布局是非常重要的,这将帮助我们更好地理解.NET的运行机制和优化代码,本文将介绍.NET中的对象内存布局。 .NET中的数据类型主要分为两类,值类型和引用类型。值类型包括了基本类型(如int、bool、double、char等)、枚举类型(enum)、结构体类型(struct),它们直接存储值。引用类型则包括了类(class)、接口(interface)、委托(delegate)、数组(array)等,它们存储的是值的引用(数据在内存中的地址)。 值类型的内存布局 值类型的内存布局是顺序的,并且是紧凑的。例如,定义的结构体SampleStruct,其中包含了四个int类型字段,每个字段占用4个字节,因此整个SampleStruct结构体在内存中占用16个字节。 public struct SampleStruct { public int Value1; …

dotnet

C#抽象静态方法

抽象静态方法 在C# 11中,引入了对抽象静态接口成员的支持。这个特性可以让你在接口中定义静态抽象方法、属性、或事件。具体来说,一个接口可以定义一个或多个抽象静态成员,这些成员没有具体的实现。任何实现该接口的类或结构必须提供这些成员的静态实现。这就像实现普通接口成员一样,只不过是静态的。当然,你也可以基于它来实现一些设计模式,本文将展开介绍。 单例模式:静态抽象成员可以用于实现单例模式。在这种模式中,一个类只能有一个实例,并提供一个全局访问点。 public interface ISingleton { static abstract ISingleton Instance { get; } } public class Singleton : ISingleton { private static readonly Singleton _instance = new …


.NET Native AOT的静态库与动态库

.NET不仅可以使用 C静态库与动态库,也可以将.NET实现的函数导出为C静态库与动态库。在没有Native Aot之前,.NET只能通过P/Invoke享受C/C++生态,而在Native Aot之后,不仅可以享受这些生态,还可以开发SDK供其他语言调用。 .NET Native AOT的NativeLib参数用于指定本机库的类型。在.NET 7中,该参数有两个选项:Static和Shared。 Static: 生成静态库,意味着所有依赖项都将被编译到生成的可执行文件中,因此它更适合独立应用程序或需要最小化依赖项的应用程序。 Shared: 生成动态库,意味着依赖项将被编译为单独的本机库,并在运行时动态加载。这种方法可以减少生成文件大小,并且更适合需要共享依赖项的应用程序,所以它也被称为共享库。 使用UnmanagedCallersOnly特性可以将C#函数导出提供给C调用, …

.NET AOT Native C

使用dotnet-monitor分析在Kubernetes的应用程序:Sidecar模式

dotnet-monitor可以在Kubernetes中作为Sidecar运行,Sidecar是一个容器,它与应用程序在同一个Pod中运行,利用Sidecar模式使我们可以诊断及监控应用程序。 如下图所示,这是我们最终要实现的目标,通过可视化界面查看应用程序的指标信息。 file 应用服务 创建dotnetmonitor.yaml文件,如下所示。 apiVersion: apps/v1 kind: Deployment metadata: name: dotnet-monitor-example spec: replicas: 3 selector: matchLabels: app: dotnet-monitor-example template: metadata: annotations: prometheus. …

.NET Kubernetes

wsl2 内存限制

在C:\Users\<UserName>\.wslconfig创建一个文件,配置如下所示。 [wsl2] memory=4GB swap=8GB swap类似于Windows的虚拟内存,从硬盘中划分出一个分区,在物理内存不够时,就会将硬盘空间虚拟成内存使用,用于解决内存不足的情况。 配置格式: [wsl2] memory=size processors=number swap=size localhostForwarding=bool 在配置设置完之后,执行wsl --shutdown命令进行关闭,随后执行wsl命令再次启动即可。 memory:限制内存 swap:交换分区 processors:限制核心数 localhostForwarding:关闭默认连接,将WSL2本地主机绑定到Windows本地主机