Anduin Xue
Anduin Xue

Anduin's Tech Blog

All Posts in 2021.9


Why you should never use `Console.WriteLine`

本文讨论了为什么在编写库代码时应避免使用`Console.WriteLine`,并提供了一些替代方案。使用`Console.WriteLine`会将库与标准输出紧密耦合,并假设调用代码关注标准输出。然而,如果库代码被单元测试套件或使用不同日志记录范例的Web服务器调用,情况将会如何? 根据依赖反转原则,高级模块不应该依赖于低级模块,而应该依赖于抽象(如接口)。此外,抽象不应该依赖于细节,细节(具体实现)应该依赖于抽象。控制台是应用程序依赖的低级模块,而日志记录是与业务相关的高级模块。因此,日志记录不应该依赖于控制台,而应该有一些抽象,如`ILogger`接口,它描述了可以提供日志记录服务的对象。 使用`Console.WriteLine`的原因有以下几点: - 无法确保控制台始终被消费和阅读。 - 需要重建项目以支持更多日志记录服务,如文件、ApplicationInsights、数据库日志记录。 - 应该遵循依赖反转原则,不依赖于低级模块,如`Console.WriteLine`。 - GUI应用程序无效,但可能提供其他日志记录窗口,如输出窗口。 - 控制台日志记录在扩展服务器端应用程序时难以跟踪和诊断。 - 难以为日志设置级别、时间戳和来源。 解决方案包括: - 使用`ILogger`代替`Console` - 使用`ILogger`的各种方法,如`ILogger.LogInformation`、`ILogger.LogCritical`等。 本文还讨论了如何获取实现`ILogger`接口的控制台日志记录器,并提供了相关的代码示例。此外,还介绍了如何在不使用依赖注入的情况下获取日志记录器的最小代码。 最后,本文指出,在某些特定情况下,可以使用`Console`类,例如构建一个终端用户界面应用程序,该应用程序永远不希望标准输出流被重定向到控制台之外的地方,或者在实现支持控制台日志记录的`ILogger`时。--GPT 4

C# .NET Core Console App .NET Logging ILogger

Install Windows store app with WinGet

This blog post demonstrates how to install a Microsoft Store app using WinGet, a Windows package manager. The process begins by obtaining the Store App ID from the Microsoft official website. Once the App ID is acquired, you can use a command to open the store page or create a PowerShell script to launch the store automatically. To install the app without a prompt, first, install WinGet using a provided script, and then run another command with the store app ID. For developers building automation, this blog post also provides a script to check if the app is already installed using the exact WinGet app name. If it's not installed, the script attempts to download and install the app. A function called Install-StoreApp is provided, making it even easier to install Microsoft Store apps with WinGet. Examples of using this function with various app IDs and WinGet app names are also included. How can you adapt these scripts for your own automation needs? And what other applications can be...--GPT 4

PowerShell Windows Winget Microsoft Store UWP Store

Install Windows 11 side-by-side without a USB drive

本篇博客文章介绍了如何在不使用USB驱动器的情况下,与现有操作系统并行安装Windows 11。首先,需要获取Windows 11的ISO文件并找到其中的Install.wim(或Install.esd)文件。接下来,在计算机上创建一个新的、干净的分区,用于安装新的Windows系统。然后,提取install.wim(esd)文件到新分区,并为新Windows添加启动项。最后,重启计算机,在启动菜单中选择新安装的操作系统即可。 在完成这个过程的过程中,你可能会遇到一些问题。例如,如何选择正确的Windows版本进行安装?如何确保新分区足够大以容纳新的操作系统?如何正确地将install.wim(esd)文件提取到新分区?以及如何确保新分区能够正常启动新的操作系统?本文详细解答了这些问题,并提供了相应的解决方案,如使用7zip打开install.wim(esd)文件,查找适合的Windows版本;使用磁盘管理工具创建新分区;以及使用命令行工具(如dism和bcdedit)完成文件提取和添加启动项等操作。 在阅读本文后,你将能够顺利地完成Windows 11的并行安装,无需依赖USB驱动器。但在实际操作过程中,你可能还会遇到其他问题,如何解决这些问题?尝试阅读全文,从中找到答案。--GPT 4

Windows 10 PowerShell Windows Windows 11 Install DISM Bcdedit Boot BCD

Retry with exponetial back-off on C#

本篇博客介绍了如何在C#中构建一个简单的重试引擎,使用指数退避算法来增加重试间隔。重试引擎的核心功能是在给定任务失败时,根据预设条件进行重试,直到达到最大尝试次数或任务成功完成。 博客中提供了一个RetryEngine类,其主要方法RunWithTry接受一个任务工厂、重试次数、错误处理条件以及超时时间作为参数。在执行任务时,若任务失败并满足重试条件,引擎会根据指数退避算法计算出一个等待时间并在此时间后进行重试。若达到最大尝试次数仍未成功,将抛出异常。 指数退避算法的实现在ExponentialBackoffTimeSlot方法中,通过计算2的次方来获取最大等待时间,并在此范围内随机选择一个时间作为实际等待时间。 在业务代码中,只需创建一个RetryEngine实例并调用RunWithTry方法即可实现任务的重试功能。例如,本文中给出了一个使用重试引擎执行网络请求的示例。 通过本文的介绍,您可以了解如何在C#中实现一个简单的重试引擎,并掌握指数退避算法的基本原理。但在实际应用中,可能还需要根据具体业务需求对重试引擎进行调整。那么,在您的项目中,如何根据实际情况调整重试策略呢?如何在保证任务成功执行的同时,避免过多的重试导致系统资源浪费?期待您的思考和实践。--GPT 4

C# .NET Retry

找到玄学问题的根源的方法 - 夹逼调试法

本文介绍了一种解决玄学问题的方法——夹逼调试法。玄学问题指的是那些在正常情况下能够正常工作,但在某些特定环境下无法正常工作的问题。夹逼调试法的核心思想是通过两个方向共同限制作用,使得问题根源的可能范围集中在最小化的条件变化中。具体操作方法包括构建一个理想环境,然后逐一对比出现问题的环境和理想环境之间的差异,通过调整这些差异,观察问题是否得到解决,从而找到可能导致问题的原因。 需要注意的是,夹逼调试法只能找到可能的原因,而不是必要、充分或充分且必要的条件。因此,该方法适用于需要快速定位可能原因的情况。本文还通过两个实际问题,详细演示了如何运用夹逼调试法进行问题定位和解决。在解决问题的过程中,我们可以发现夹逼调试法具有一定的实用性和效率,对于解决那些难以预料的因素导致的问题具有一定的参考价值。那么,在面对类似的玄学问题时,你是否会尝试运用夹逼调试法来寻找问题的根源呢?--GPT 4