lindexi

林德熙 - 微软最具价值专家和 .NET 基金会成员

林德熙

dotnet 解析 TTF 字体文件格式

在 Windows 下,可以使用 DX 提供的强大能力,调用 DX 读取 TTF 字体文件,获取字体文件的信息以及额外的渲染信息。特别是基于 DX 的 WPF 更是加了一层封装,使用 FontFamily 类型提供的友好方法获取到字体的信息。出于学习的目的,本文将不使用任何平台封装好的方法,自己读取二进制的 TTF 文件,解析 TTF 的内容,获取到字体文件里面的字体名

dotnet 使用 ConfigureAwait.Fody 库设置默认的 await 同步上下文切换配置

在 dotnet 里面,使用 await 进行异步逻辑,默认是会尝试切换回调用 await 的线程同步上下文。这个机制对于大多数的上层应用来说都是符合逻辑且方便的逻辑,例如对于带 UI 线程的 WPF 或 WinForms 等应用,基础开发的执行逻辑基本都是在 UI 线程上,此时进入一次 await 再出来,期望如果是进入 await 之前是在 UI 线程,那么执行 await 完成之后,退出的代码也能在 UI 线程执行,正好这就是 dotnet 的默认行为。但是对于库开发者来说,情况就反过来的,库的开发者大部分时候更期望默认不要切换回调用方的线程,采用 Fody 的 ConfigureAwait.Fody 库,可以控制此默认的行为。本文将告诉大家如何使用 ConfigureAwait.Fody 库

dotnet 为大型应用接入 ApplicationStartupManager 启动流程框架

对于大型的应用软件,特别是客户端应用软件,应用启动过程中,需要执行大量的逻辑,包括各个模块的初始化和注册等等逻辑。大型应用软件的启动过程都是非常复杂的,而客户端应用软件是对应用的启动性能有所要求的,不同于服务端的应用软件。设想,用户双击了桌面图标,然而等待几分钟,应用才启动完毕,那用户下一步会不会就是点击卸载了。为了权衡大型应用软件在启动过程,既需要执行复杂的启动逻辑,又需要关注启动性能,为此过程造一个框架是一个完全合理的事情。我所在的团队为启动过程造的库,就是本文将要和大家介绍我所在团队开源的 dotnetCampus.ApplicationStartupManager 启动流程框架的库

dotnet 使用 TaskTupleAwaiter 同时等待多个任务简化代码写法

在某些业务逻辑下,需要同时等待多个任务执行完成,才能继续往下执行后续逻辑。等待任务执行的逻辑,大部分情况下需要使用到 Task.WhenAll 方法,代码行数不少。另外,在需要获取多个异步任务的返回值的逻辑上,整体的逻辑代码量看起来也不少。本文将和大家介绍 TaskTupleAwaiter 库,通过 TaskTupleAwaiter 库可以方便等待多个任务执行完成,且方便获取各个异步任务的返回值

dotnet 使用 Newtonsoft.Json 输出枚举首字符小写

本文告诉大家如何使用 Newtonsoft.Json 输出枚举首字符小写

dotnet 使用 IndentedTextWriter 辅助生成代码时生成带缩进的内容

随着源代码生成的越来越多的应用,自然也遇到了越来越多开发上的坑,例如源代码的缩进是一个绕不过去的问题。如果源代码生成是人类可见的代码,我期望生成的代码最好是比较符合人类编写代码的规范。为了能让人类在阅读机器生成的代码的时候,不会想着拿刀砍那个编写代码生成代码的开发者,最好,或者说至少代码也应该有个缩进和换行吧。本文将安利大家通过 IndentedTextWriter 这个辅助类,用来辅助生成带缩进的内容

dotnet OpenXML 解析 PPT 图表 面积图入门

本文告诉大家如何使用 OpenXML 解析 PPT 的图表,以面积图为入门例子告诉大家 OpenXML 的存储

dotnet 6 使用 File.Exists 判断管道是否存在将让下次连接失败

我尝试在 dotnet 6 使用 File.Exists 判断管道是否存在,如果管道存在再进行连接。然而这个逻辑将会接下来的 NamedPipeClientStream 调用 Connect 连接失败

dotnet 6 精细控制 HttpClient 网络请求超时

本文告诉大家如何在 dotnet 6 下使用 HttpClient 更加精细的控制网络请求的超时,实现 HttpWebRequest 的 ReadWriteTimeout 功能

dotnet OpenXML 解析 PPT 图表 解析日期时间表示内容

在 OpenXML 里的图表存放的日期时间很多存放的是数值,需要进行转换才能获取到用户可见的字符串

dotnet 6 通过 DOTNET_ROOT 让调起的应用的进程拿到共享的运行时文件夹

我的应用是独立发布的,在用户的设备上不需要额外去安装 .NET 运行时。但是我的应用有一个需求是下载另一个应用作为插件,由本应用调起插件进程。本文告诉大家如何解决调用插件的进程时,赋值给插件进程运行时的文件夹路径,解决环境依赖

dotnet 5 的 bin 文件夹下的 ref 文件夹是做什么用的

本文来和大家聊聊在 dotnet 5 和 dotnet 6 或更高版本的 dotnet 构建完成,在 bin 文件夹下,输出的 ref 文件夹。在此文件夹里面,将会包含项目程序集同名的 dll 文件,但是此 dll 文件的大小却很小,那这个文件夹是用来做什么的

WPF 简单判断主线程界面是否卡顿的方法

本文来告诉大家如何使用简单的代码判断当前的软件的 UI 线程或界面是否卡顿

读书笔记 dotnet 的字符串在内存是如何存放

本文是读伟民哥翻译的 .NET内存管理宝典 这本书的笔记,我认为读书的过程也需要实践,这样对一知半解的知识也有较为清晰的了解。在阅读到 string 在内存的布局时,我看到 RuntimeHelpers 的 OffsetToStringData 数据,据说此属性可以获取到字符串的字符在内存存放的实际地址,本文将来写一个混合 C# 和 C++\CLI 的应用来进行测试

读书笔记 为什么要有R5G6B5颜色格式

在 Windows 下,颜色的格式有很多,我好奇为什么要设计出 R5G6B5 这样的格式?通过阅读一些书和官方的文档,似乎了解了为什么,我在本文记录一下

记因为 NVIDIA 显驱错误而让 WPF 应用启动闪退问题

本文记录一个因为 NVIDIA 显卡驱动错误而让 WPF 应用启动闪退问题

记 Win8.1 某应用渲染抛出 OutOfMemoryException 异常及修复方法

本文记录某个应用在某台 Windows 8.1 x86 系统上,运行时抛出 OutOfMemoryException 异常,启动失败。应用程序能启动,但是在第一次碰到渲染时,就发现渲染初始化失败,从而让应用程序闪退

用 SetWindowPos 方法设置一个停止响应的窗口将卡调用方

我使用 User32 的 SetWindowPos 方法去设置一个跨进程的窗口,这个窗口是停止响应的,将让调用的 SetWindowPos 方法卡住,不继续执行逻辑。通过堆栈分析是卡在 NtUserSetWindowPos 方法上,调用 SetWindowPos 方法不返回

WPF 全屏窗口将让 Chrome 97 视频停止播放

无论是使用 WPF 全屏窗口,还是高性能全屏透明窗口,都会在 Chrome 97 以及使用 chromium 对应版本内核的应用的视频停止播放。这是 chromium 的一个优化,因为 chromium 认为,如果有全屏窗口盖在上面,自然此时停止播放视频可以节省资源。然而 chromium 却没有考虑到,有很多会议的应用,虽然是全屏的,但也是透明的,于是此时停止播放视频将是非预期的

WPF 使用 Skia 解析绘制 SVG 图片

本文告诉大家如何在 WPF 里面,使用 Skia 解析绘制 SVG 图片。本文也适合控制台使用 SkiaSharp 解析绘制 SVG 图片,本文的 WPF 部分只是在 Skia 绘制完成之后,将 Skia 的内容绘制到 WPF 的 WriteableBitmap 图片,从而在界面显示

WPF dotnet 6 开启 PM v2 的 DPI 感知 导致触摸线程访问 UI 属性抛异常

本文记录一个 WPF 在 dotnet 6 的一个已知问题,且此问题我已修复提交给官方仓库。这是一个只有在 dotnet 6 框架下,非 dotnet 5 也非 .NET Core 3.1 也非 .NET Framework 的问题,要求开启 DPI 感觉等级为 PerMonitorV2 的特性,在带触摸屏上的应用,应用运行过程中,切换屏幕的 DPI 之后,触摸过程有概率触发在触摸线程访问 UI 的依赖属性,在触摸线程抛出异常炸掉应用

UWP 从文件 StorageFile 转 SoftwareBitmap 图片方法

本文告诉大家如何在 UWP 从 文件 StorageFile 转 SoftwareBitmap 图片的方法

Ubuntu 通过本机代理修复 NuGet 还原 error NU1301 失败

在国内垃圾的网络环境下,我在虚拟机里面安装了 Ubuntu 系统,准备用来测试 MAUI 在 Linux 上的行为,然而使用 dotnet restore 构建时,提示 NU1301 失败。我通过配置环境变量的方式,让 nuget 还原使用上我物理机的网络代理,成功将 NuGet 包下载

SkiaSharp 渲染输出 SVG 文件

谷歌的 Skia 的一个卖点就是提供了完美的 SVG 的支持,包括输入和输出。输入指的是给一张 SVG 图片,将这个 SVG 渲染出来。输出就是将输出画面保存为 SVG 格式的图片。自然 SkiaSharp 是 Skia 的封装,也就带上了此功能。本文将告诉大家如何在 SkiaSharp 里面设置画面输出为 SVG 图片,使用 SkiaSharp 制作和编辑 SVG 图片

Microsoft.Maui.Graphics.Skia 使用 DrawString 绘制文本的坐标问题

本文记录使用 Microsoft.Maui.Graphics.Skia 的 DrawString 进行绘制文本,不同的重载方法绘制的文本的坐标不同的问题

FileStream 的 FlushAsync 方法在 .NET Framework 与 .NET Core 行为的不同

本文记录 FileStream 的 FlushAsync 方法在 .NET Framework 与 .NET Core 行为的不同

dotnet 谨慎在静态构造函数里使用锁

在 dotnet 的最佳实践里面,不推荐在静态构造函数里面包含复杂的逻辑,其中也就包含了本文聊的和多线程相关的锁的使用。最佳做法是尽量不要在静态构造函数里面碰到任何和锁以及多线程安全相关的逻辑。本文来告诉大家,在静态构造函数里面使用锁将带来的问题以及原因

dotnet 读 WPF 源代码笔记 WPF 是如何做到一套代码兼容多个 .NET Framework 版本

在 .NET Framework 时代里面,有一组有趣的概念,那就是 SDK 和 Runtime 这两个概念。开发模式十分有趣,在开发者设备上,可以指定 .NET Framework 的 SDK 版本,例如指定 .NET Framework 4.5 版本。开发完成之后,分发给到用户,用户的电脑上所安装的 .NET Framework 基本都是 Runtime 版本。应用程序要求运行的 Runtime 版本一定要大于等于 SDK 的指定版本号 这就有一个非常有趣的问题了,我开发环境使用的 SDK 是低版本,例如 .NET Framework 4.5 版本。但用户的电脑上所安装的 .NET Framework 的 Runtime 版本是高版本,例如是 .NET Framework 4.7 版本,中间距离过了几年的版本。那行为如何保证相同?如果行为不能保证相同,那将会出现行为差异,在我的开发设备上跑得好好的,在一些用户电脑上,将会因为运行时基础库的版本差异从而变更行为,应用程序就不能符合预期跑起来了。事实上,咱没有碰到过这个问题,这是因为在 .NET Framework 层做了很多兼容处理逻辑,其中就包括本文要和大家聊的 WPF 框架的兼容行为

dotnet 开启 Fiddler 抓包将会让请求 HOST 头被更改

我在写域名备份功能,想要修改请求的 IP 地址,同时又将原有的请求域名带上。实现方法是修改请求的地址,在 HttpRequestMessage 的 Header 上添加 HOST 记录,记录的值就是原有的域名。然而在开启 Fiddler 之后,将会发现实际发出的请求的 HOST 是实际请求的地址

dotnet 使用 NamedPipeClientStream 连接一个不存在管道服务名将不断空跑 CPU 资源

本文记录一个开发和代码审查过程中,需要关注的细节。在 dotnet 里,在 .NET 6 和以下版本,包括 .NET Framework 版本,使用 NamedPipeClientStream 进行连接管道服务,如果此时的管道服务没有存在,或者还没有启动,调用 ConnectAsync 或 Connect 方法,将会进入一个循环,不断进行空跑,等待超时或者是连接上。默认的 ConnectAsync 或 Connect 方法,传入的超时时间都是无穷,也就是将会无限重试,不断消耗 CPU 资源

读 MAUI 源代码 理解可绑定对象和可绑定属性的存储机制

和 UWP 与 WPF 不同的是在 MAUI 里面,使用可绑定对象 BindableObject 替换了依赖对象的概念,我阅读了 MAUI 的源代码发现其实只是命名变更了,里面的机制和设计思想都是差不多的。在 MAUI 里面提供 BindableObject 用来支持可绑定属性机制和附加属性机制,本文将告诉大家在 MAUI 里面是如何在可绑定对象里面提供可绑定属性和附加属性的存储的机制

dotnet OpenXML 使用 MAUI 渲染 PPT 的面积图图表

我在做一个图表工具软件,这个软件使用 MAUI 开发。我的需求是图表的内容需要和 PPT 的图表对接,需要用到 OpenXML 解析 PPT 内容,读取到 PPT 图表元素的内容,接着使用 MAUI 渲染层绘制图表元素。图表工具软件需要在 Windows 平台和 Linux 平台上运行。在 Windows 下,我采用 WPF 应用,用来辟谣说 MAUI 不支持 WPF 应用。 在 Linux 选用 Ubuntu 系统,采用 GTKSharp 应用加上 Skia 渲染对接 MAUI 框架

dotnet C# 图片等比限制最大和最小大小缩放算法

本文只是告诉大家如何计算缩放之后的宽度和高度,不包含实际的图片缩放方法

C# dotnet 使用 OpenXml 解析 PPT 里面的视频

本文告诉大家如何从 PPTX 文件里面解析出视频