<?xml version="1.0" encoding="utf-16"?><rss version="2.0"><channel><title>HueiFeng</title><description>冯辉,HueiFeng,.NET,.NET Core,Docker,k8s</description><link>https://hueifeng.azurewebsites.net/</link><pubDate>Sun, 05 Apr 2026 11:19:01 GMT</pubDate><copyright>(c) {year} Moonglade</copyright><generator>Moonglade v11.2-preview</generator><item><title>把 Kubernetes 的调度思想带入 .NET：开源分布式任务框架 KubeJob 正式发布！</title><link>https://hueifeng.azurewebsites.net/post/2026/3/7/bringing-kubernetes-scheduling-to-dotnet-with-kubejob</link><description>背景与痛点：我们为什么又造了一个“轮子”？
在 .NET 生态中，提到后台任务调度，我们通常会想到 Quartz.NET、Hangfire 或者是 ASP.NET Core 自带的 BackgroundService。它们都非常优秀，但在现代云原生和微服务架构下，我们有时会面临一些新的挑战：
原生定时器的局限：简单的 Timer 或 IHostedService 缺乏分布式协调能力，多实例部署时容易导致任务重复执行，且没有可视化界面监控状态。
传统框架的厚重：某些成熟的调度框架与特定存储或设计模式深度绑定，对于只需要轻量级分布式调度和可视化管理的团队来说，接入成本较高。
缺乏现代化的调度策略：在集群环境中，我们往往希望任务能像 Kubernetes 调度 Pod 一样，具有“节点标签选择 (Node Selector)”、“广播执行 (Broadcast)”、“分片执行 (Sharded) …</description><author>695979933@qq.com</author><category>.NET</category><category>C#</category><guid isPermaLink="false">C1B5F49D-A33A-405D-B2A9-E6F2665927D3</guid><pubDate>Sat, 07 Mar 2026 10:31:10 GMT</pubDate></item><item><title>.NET解决方案格式升级：SLN与SLNX</title><link>https://hueifeng.azurewebsites.net/post/2025/3/22/dotnet-solution-format-upgrade-sln-vs-slnx</link><description>在.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\ …</description><author>695979933@qq.com</author><category>.NET</category><guid isPermaLink="false">8D903473-C3B6-49F2-B1CA-96762D184F2C</guid><pubDate>Sat, 22 Mar 2025 15:01:44 GMT</pubDate></item><item><title>Visual Studio项目文件中的SCC配置属性</title><link>https://hueifeng.azurewebsites.net/post/2025/3/21/visual-studioscc-560ba2e3</link><description>Visual Studio 项目文件 SCC 属性配置指南
一、SCC 属性概述
在传统的 .csproj/.vbproj 项目文件中，&lt;PropertyGroup Label="Globals"&gt; 节点下的 ‌SCC 属性‌用于定义项目与源代码控制系统（如 TFS、SVN、VSS 等）的集成配置。这些属性常见于旧版 Visual Studio（2010-2017）创建的项目，对团队协作开发至关重要。
二、核心属性详解
1. &lt;SccProjectName&gt;
▫️ 作用
定义项目在源代码控制系统中的‌唯一标识名称‌，对应服务端存储路径的映射标识。
▫️ 典型值
SccProjectNameMyProject/Trunk/Source/SccProjectName
当值为 SAK（Should Already Know）时，表示 IDE 应自动识别绑定关系。
2. &lt;SccProvider&gt; …</description><author>695979933@qq.com</author><category>.NET</category><guid isPermaLink="false">56123997-33D1-4F2D-BC49-FCC63B29986C</guid><pubDate>Fri, 21 Mar 2025 08:52:19 GMT</pubDate></item><item><title>理解并掌握C#的Channel：从使用案例到源码解读（一）</title><link>https://hueifeng.azurewebsites.net/post/2023/9/24/mastering-csharp-channels-part-one</link><description>引言
在C#的并发编程中，Channel是一种非常强大的数据结构，用于在生产者和消费者之间进行通信。本文将首先通过一个实际的使用案例，介绍如何在C#中使用Channel，然后深入到Channel的源码中，解析其内部的实现机制。
使用案例一：文件遍历和过滤
在我们的使用案例中，我们需要遍历一个文件夹及其所有子文件夹，并过滤出具有特定扩展名的文件。在此，我们使用了C#的Channel来实现这个任务。
首先，我们创建了一个名为EnumerateFilesRecursively的方法，这个方法接受一个文件夹路径作为参数，并返回一个ChannelReader&lt;string&gt;。这个方法中，我们创建了一个有界的Channel，然后在一个单独的任务中遍历指定的文件夹及其所有子文件夹，并将找到的每个文件的路径写入Channel。当遍历完成后，我们关闭Channel的写入端。 …</description><author>695979933@qq.com</author><category>.NET</category><guid isPermaLink="false">CF239415-18C6-4F58-8316-2568E1207954</guid><pubDate>Sun, 24 Sep 2023 15:33:35 GMT</pubDate></item><item><title>.NET对象的内存布局</title><link>https://hueifeng.azurewebsites.net/post/2023/8/6/dotnet-objectmemory-layout</link><description>在.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; …</description><author>695979933@qq.com</author><category>.NET</category><category>C#</category><guid isPermaLink="false">874735CB-D6B6-4C40-9A8C-0CD9F15E1D5E</guid><pubDate>Sun, 06 Aug 2023 14:14:48 GMT</pubDate></item><item><title>C#抽象静态方法</title><link>https://hueifeng.azurewebsites.net/post/2023/7/15/csharp-static-abstract</link><description> 抽象静态方法
在C# 11中，引入了对抽象静态接口成员的支持。这个特性可以让你在接口中定义静态抽象方法、属性、或事件。具体来说，一个接口可以定义一个或多个抽象静态成员，这些成员没有具体的实现。任何实现该接口的类或结构必须提供这些成员的静态实现。这就像实现普通接口成员一样，只不过是静态的。当然，你也可以基于它来实现一些设计模式，本文将展开介绍。
单例模式：静态抽象成员可以用于实现单例模式。在这种模式中，一个类只能有一个实例，并提供一个全局访问点。
public interface ISingleton
{
    static abstract ISingleton Instance { get; }
}

public class Singleton : ISingleton
{
    private static readonly Singleton _instance = new …</description><author>695979933@qq.com</author><category>.NET</category><guid isPermaLink="false">4CDA38FE-CBD2-4906-B095-E9B6ED245E48</guid><pubDate>Sat, 15 Jul 2023 14:18:18 GMT</pubDate></item><item><title>.NET Native AOT的静态库与动态库</title><link>https://hueifeng.azurewebsites.net/post/2023/5/16/net-native-aot</link><description>.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调用， …</description><author>695979933@qq.com</author><category>.NET</category><guid isPermaLink="false">1E4C7792-92DC-449C-BD24-0F0A8A79C9D4</guid><pubDate>Tue, 16 May 2023 14:18:48 GMT</pubDate></item><item><title>使用dotnet-monitor分析在Kubernetes的应用程序：Sidecar模式</title><link>https://hueifeng.azurewebsites.net/post/2022/8/17/dotnetmonitorkubernetessidecar</link><description>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. …</description><author>695979933@qq.com</author><category>.NET</category><guid isPermaLink="false">91EA438E-0A40-4C89-B670-D1ADBC798DFC</guid><pubDate>Wed, 17 Aug 2022 15:32:36 GMT</pubDate></item><item><title>wsl2 内存限制</title><link>https://hueifeng.azurewebsites.net/post/2022/7/27/limit-wsl-memory</link><description>在C:\Users\&lt;UserName&gt;\.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本地主机
</description><author>695979933@qq.com</author><category>Docker</category><guid isPermaLink="false">83A2614E-9688-41C8-8C41-C587502BAA4A</guid><pubDate>Wed, 27 Jul 2022 15:21:00 GMT</pubDate></item><item><title>利用Windbg分析Magicodes.IE一次错误编写导致内存问题</title><link>https://hueifeng.azurewebsites.net/post/2021/12/11/windbgmagicodesie</link><description>由于这近一年时间一直忙于写书和工作，一直没有水文，但是近期有几位朋友使用我们的Magicodes.IE反馈在导出过程中内存暴涨...好吧，不管怎样，不能苦了我们朋友，接下来我们通过windbg来看一下什么原因导致的。
接下来我们先通过address -summary来看一下当前应用内存占用量。
0:000 !address -summary

--- Usage Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
Free                                    581     7df8`ef0c9000 ( 125.972 TB)           98.42%
unknown                              1678 …</description><author>695979933@qq.com</author><category>.NET</category><guid isPermaLink="false">91BCF231-42C7-4C0B-A149-9A957A539874</guid><pubDate>Sat, 11 Dec 2021 06:54:45 GMT</pubDate></item><item><title>【Azure DevOps系列】Azure DevOps构建.NET EFCore应用程序</title><link>https://hueifeng.azurewebsites.net/post/2021/5/30/azure-devopsazure-devopsnet-efcore</link><description>本章我们将看到如何通过Azure DevOps使用EFCore CLI工具将我们的EFCore应用程序进行数据库重建，当然这种操作我不建议使用，建议使用CLI生成sql脚本形式进行发布并迁移。
设置代理服务器sdk
- task: UseDotNet@2
  inputs:
    packageType: 'sdk'
    version: '3.x'
安装dotnet-ef
安装Entity Framework Core CLI工具，用于后面对数据库的操作
- task: CmdLine@2
  displayName: 'install dotnet-ef'
  inputs:
    script: 'dotnet tool install -g dotnet-ef'
删除数据库
 dotnet ef database drop --project &lt;path to your …</description><author>695979933@qq.com</author><category>.NET</category><category>.NET5</category><category>ASP.NET CORE</category><category>Azure</category><category>ASP.NET Core 5.0</category><guid isPermaLink="false">6B08EC4E-24A5-4BB3-ADF7-F8D07619F5C1</guid><pubDate>Sun, 30 May 2021 04:46:38 GMT</pubDate></item><item><title>.NET RulesEngine（规则引擎）</title><link>https://hueifeng.azurewebsites.net/post/2021/4/29/dotnetnet-rulesengine</link><description>一次偶然的机会，让我拿出RulesEngine去完成一个业务，对于业务来说主要是完成一个可伸缩性（不确定的类型，以及不确定的条件，条件的变动可能是持续增加修改的）的业务判断。比如说完成一个成就系统，管理员可创建，对于成就来说有一次性解锁、日常、周常式，还有随时重置，每次达成都触发的，面对着成就任务的增加，那对于程序员来说，如果每次都去增加修改这些成就任务简直是太头疼了。好了，对此大家应该有一个简单的了解了，那跟着笔者往下走，我们看看如何在.NET中使用非常少的代码去完成一个简单的动态逻辑处理。
RulesEngine 概述
RulesEngine是Microsoft推出的一个规则引擎项目，用于系统中抽象出的业务逻辑/规则/策略。在我们开发的过程中，避免不了的是跟这种反反复复的业务逻辑进行处理，而对于这种动态的规则来说的话，它是比较优雅的一种方式，使用我们减少了对我们代码或者说项目的修改。 …</description><author>695979933@qq.com</author><category>.NET</category><category>.NET5</category><guid isPermaLink="false">41F9E03F-7E43-4184-BA3C-B771401053C4</guid><pubDate>Thu, 29 Apr 2021 15:13:59 GMT</pubDate></item><item><title>在ASP.NET Core中使用ViewComponent</title><link>https://hueifeng.azurewebsites.net/post/2021/4/10/using-viewcomponents-in-asp-net-core</link><description>前言
在之前的开发过程中，我们对于应用或者说使用一些小的组件，通常使用分布页（partial view），再往前在Web Form中我们会进行应用WEB Control，好吧提及一个关键性代码TagPrefix：TagName，通过这种的标记我们便可以在我们web form中进行引入我们的组件，当然自从.NET MVC之后呢，就已经没有了WebControl，而对于.NET Core后，又多了一个特性ViewComponent。
对于ViewComponent看起来它类似于小的控制器，而对于我们小的组件或者小部分通用型功能，可通过ViewComponent进行实现，比如说留言栏、菜单等等。
ViewComponent是由两部分组成，一部分是类（通常该类集成与ViewComponent），而另外一部分是视图（Razor和普通的View一样），当然ViewComponent同样也支持POCO， …</description><author>695979933@qq.com</author><category>ASP.NET MVC</category><category>.NET</category><category>ASP.NET CORE MVC</category><category>.NET5</category><category>ASP.NET CORE</category><category>ASP.NET Core 5.0</category><guid isPermaLink="false">A4118DBF-0C7B-4658-9017-F8498E038D60</guid><pubDate>Sat, 10 Apr 2021 03:40:30 GMT</pubDate></item><item><title>.NET初探源代码生成（Source Generators）</title><link>https://hueifeng.azurewebsites.net/post/2021/3/16/generating-code-in-dotnet</link><description>前言
Source Generators顾名思义代码生成器，可进行创建编译时代码，也就是所谓的编译时元编程，这可让一些运行时映射的代码改为编译时，同样也加快了速度，我们可避免那种昂贵的开销，这是有价值的。
实现ISourceGenerator
集成ISourceGenerator接口，实现接口用于代码生成策略，它的生命周期由编译器控制，它可以在编译时创建时创建并且添加到编译中的代码，它为我们提供了编译时元编程，从而使我们对C#代码或者非C#源文件进行内部的检查。
    [Generator]
    class CustomGenerator: ISourceGenerator
    {
        public void Initialize(GeneratorInitializationContext context)
        {
            throw …</description><author>695979933@qq.com</author><category>.NET</category><category>.NET5</category><category>ASP.NET CORE</category><guid isPermaLink="false">88056697-3937-49EA-9257-07B3FEA3F28F</guid><pubDate>Tue, 16 Mar 2021 12:43:48 GMT</pubDate></item><item><title>.NET探索模型路由约定实现伪静态</title><link>https://hueifeng.azurewebsites.net/post/2021/2/19/dotnet-implement-url-rewrite</link><description>概述
IPageRouteModelConvention接口用于自定义PageRouteModel，这个对象在Microsoft.AspNetCore.Mvc.ApplicationModels命名空间中，
代表着Razor Page路由设置，换句话说我们可以通过实现该接口覆盖默认的实现。
该接口需要实现一个成员void Apply(PageRouteModel model)。通过这个方法，我们可以访问有关当前路由设置的元数据，并根据需要对其内容进行修改。
下面示例，将解决提供一个伪静态的解决方案，因此我们可以通过index.html about.html....去访问我们的页面，也就是说我们可以从Index-Index.html的支持
    public class HtmlExtensionPageRouteModelConvention : …</description><author>695979933@qq.com</author><category>.NET</category><category>.NET5</category><category>ASP.NET CORE</category><category>ASP.NET Core 5.0</category><guid isPermaLink="false">7946ECA2-A86C-4CE0-AB9E-0FCC73CBDFA6</guid><pubDate>Fri, 19 Feb 2021 10:49:28 GMT</pubDate></item><item><title>.NET中使用DebuggerDisplay轻松定制调试</title><link>https://hueifeng.azurewebsites.net/post/2021/2/12/debugging-your-dotnet-application-more</link><description>前言
对于调试的方式有多种，不过在今天我们将看到的监视窗口对变量的监视，当然在这里我们是定制内部的变量值，或者说变量的显示与计算的内容。
注：监视窗口在调试时可以一次显示多个变量。“快速监视”对话框一次显示一个变量。
file
DebuggerDisplayAttribute
在下面示例中，我们在类上添加DebuggerDisplay，添加字符串：("Name={Name},Age={Age}")：
 class Program
    {
        static void Main(string[] args)
        {
            Student student = new Student()
            {
                Name = Mr.A,
                Age = 18
            }; …</description><author>695979933@qq.com</author><category>.NET</category><category>.NET5</category><guid isPermaLink="false">67B3E5EA-90EC-45AD-9266-9A3D0AA8A13E</guid><pubDate>Fri, 12 Feb 2021 12:46:59 GMT</pubDate></item><item><title>.NET探索平台条件编译</title><link>https://hueifeng.azurewebsites.net/post/2021/1/17/dotnet-exploration-platform-condition-compilation</link><description>前言
今天偶然机会，翻了一下大学期间的书籍《C程序设计》，好吧，当我翻着翻着，翻到了符号常量（#define指令）中，是啊，这是一个预处理器指令，记得在Magicodes.IE中针对平台选择不同的库，哈哈，这是一个典型的根据平台进行条件处理，好吧，
根据这些内容，让我感觉在今天，我需要对#define指令以及在.NET中的平台条件处理，以及平台的条件编译进行记录一下。
file
define
我们可通过define来定义符号，然后将符号用在#if指令表达式中，如下所示：
#define PI
通过上面这些内容可能很难去了解这该如何使用，其实#define在我们的编码过程中也是很少去使用的，我们继续往下看。
其实对于预处理器，在我们调试以及运行时的作用是比较大的，比如说对某些代码限制编译，另一方变其实还可以对代码进行环境或者版本的控制，这些都是Ok的，最后我们结合着控制语句#if来看一下: …</description><author>695979933@qq.com</author><category>.NET</category><guid isPermaLink="false">F7306072-050F-488B-B2B2-39CCF78275FA</guid><pubDate>Sun, 17 Jan 2021 14:36:04 GMT</pubDate></item><item><title>【Azure DevOps系列】Azure DevOps EFCore命令式脚本部署到SQL数据库</title><link>https://hueifeng.azurewebsites.net/post/2020/12/9/azure-devopsazure-devops-efcoresql</link><description>构建迁移脚本
为了构建迁移脚本，我们将需要使用EF Tools for Command Line Interface。这些工具在Microsoft.EntityFrameworkCore.Tools提供。
迁移脚本
现在我们将通过 dotnet ef migrations script –p path to your csproj with migrations -o $(Build.ArtifactStagingDirectory)\migrations\scripts.sql –i来迁移我们的脚本，在如下代码片段中我将脚本进行迁移出来并且输出到指定的路径 -o $(Build.ArtifactStagingDirectory)/migrations/scripts.sql中，	-i代表生成可用于任何迁移的数据库的脚本。
 - task: CmdLine@2 …</description><author>695979933@qq.com</author><category>Azure</category><category>DevOps</category><guid isPermaLink="false">BF6EB13E-F56A-4F9B-AB2E-5F930856FA9E</guid><pubDate>Wed, 09 Dec 2020 13:23:52 GMT</pubDate></item><item><title>探索.NET平台中的SIMD内在函数Vector</title><link>https://hueifeng.azurewebsites.net/post/2020/12/1/netsimdvector</link><description>概述
Vector（向量）是一种序列式容器，事实上和数组差不多，但它比数组更优越。一般来说数组不能动态拓展，因此在程序运行的时候不是浪费内存，就是造成越界。而Vector刚好弥补了这个缺陷，它的特征是相当于可分配拓展的数组（动态数组），它的随机访问快，在中间插入和删除慢，但在末端插入和删除快。
什么是SIMD？
SIMD是Single Instruction Multiple Data的缩写，通常中文译为单指令多数据流，通俗来讲的话是：对多个数据执行同一个CPU指令，以达到平行运算的目的.
在GPU之前我们会通过CPU来运行该项技术来增加图片的运算速度，例如Intel的MMX、SSE、SSE2、AVX，AMD的3DNow!等等，都是来使用SIMD
为基础的概念，在GPU技术突飞猛进的今天，CPU的SIMD技术很少用在了图片运算方面了，更多的是在资料库或者其他用途上。
SIMD
它适用于机器 …</description><author>695979933@qq.com</author><category>.NET</category><category>.NET5</category><guid isPermaLink="false">2E963547-9B39-46BD-B93A-8AEC8FFA127D</guid><pubDate>Tue, 01 Dec 2020 02:57:11 GMT</pubDate></item><item><title>Vs编译时RazorTagHelper - DOTNET_HOST_PATH is not set</title><link>https://hueifeng.azurewebsites.net/post/2020/11/17/vs-razortaghelper-dotnethostpath-is-not-set</link><description>今天听朋友说遇到一个问题，打开一个aspnetcore2.2的项目工程，发现挺有意思，缺少环境变量DOTNET_HOST_PATH
file
严重性	代码	说明	项目	文件	行	禁止显示状态
错误	MSB4018	“RazorTagHelper”任务意外失败。
System.InvalidOperationException: DOTNET_HOST_PATH is not set
   在 Microsoft.AspNetCore.Razor.Tasks.DotNetToolTask.get_DotNetPath()
   在 Microsoft.AspNetCore.Razor.Tasks.DotNetToolTask.GenerateFullPathToTool()
   在 Microsoft.Build.Utilities.ToolTask.ComputePathToTool() …</description><author>695979933@qq.com</author><category>ASP.NET CORE MVC</category><category>ASP.NET CORE</category><guid isPermaLink="false">82DC7BE7-292B-48F4-9192-82128D27D220</guid><pubDate>Tue, 17 Nov 2020 12:26:11 GMT</pubDate></item></channel></rss>