Skip to content

Commit a2cdec6

Browse files
committed
public 49 episode
1 parent bcd9774 commit a2cdec6

File tree

2 files changed

+212
-1
lines changed

2 files changed

+212
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
### 2024
1717

18-
**一月份**[048](docs/episode-048.md) :high_brightness:
18+
**一月份** [049](docs/episode-049.md) :high_brightness: | [第 048 期](docs/episode-048.md)
1919

2020
### 2023
2121

docs/episode-049.md

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
# .NET 每周分享第 49 期
2+
3+
## 卷首语
4+
5+
C# 成为年度语言? 这里有一个有趣的不同的[观点](https://www.youtube.com/watch?v=5omutyj6N0Q&t=409s&ab_channel=NickChapsas)
6+
7+
在过去的一段时间,`.NET` 社区最大的新闻是 `C#` 被 Tiobe 评选为 2023 年度编程语言。几乎所有的媒体都在欢呼雀跃,那么事实真的如此吗?
8+
9+
1. Tiobe 评选的标准是增加量
10+
2. 结果并不会改变立刻任何事情
11+
3. Tiobe 的选择的可靠性不高
12+
13+
## 文章推荐
14+
15+
1、[StringValue 探秘](https://andrewlock.net/a-brief-look-at-stringvalues/)
16+
17+
`Microsoft.Extensions.Primitives` 包中有一个类型是 `StringValues`, 它可以用在表示 `HTTP` Header 中,可以表达三种情况,
18+
19+
1. 没有 Header
20+
2. 单个 Header
21+
3. 多个 Header
22+
23+
那么在 `ASP.NET Core` 中,该如何表示这个对象呢?
24+
25+
- 朴素表达方式
26+
27+
使用 `Dictionary<string, string[]>` 类型表达,因为上述三种情况都可以表示,但是这个存在两个问题:
28+
29+
1. 大部分情况下,只有一个值,但是还是需要多个情况
30+
2. 将单个值存储为一个数组,增加内存分配
31+
32+
- `NameValueCollection`
33+
34+
`ASP.NET` 中使用 `NameValueCollection` 类型,但是它本质还是使用 `ArrayList` 存储内容, 所以还是不够优雅。
35+
36+
`StringValues` 使用一个 `object` 表示上述的三种情况,也是一个 `readonly struct` 类型。
37+
38+
2、[.NET 8 中 Random](https://henriquesd.medium.com/net-8-new-randomness-methods-f2422f55320f)
39+
40+
![image](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/467d1215-43b6-4500-b877-ff290315c463)
41+
42+
.NET 8 在 `Random` 类中提供了一些新的方法,比如
43+
44+
1. GetItems
45+
46+
当我们在一个集合中随机选择一定数量时候,可以使用 `GetItems`, 比如 `Random.Shard.GetItems`
47+
48+
2. Shuffle
49+
50+
如果对一个集合进行混洗,可以使用 `Shuffle`, 比如 `Random.Shard.Shuffle`
51+
52+
3、[.NET 8 中并行启动 IHostedService](https://www.youtube.com/watch?v=n4tzpRB2lzc&ab_channel=MilanJovanovi%C4%87)
53+
54+
![image](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/d39de28d-cf1f-4415-b72a-0e300b8390d4)
55+
56+
`IHost` 中,在执行 `Run` 方法的时候,会获取所有的注册的 `IHostedService` 取出来,然后执行 `StartAsync` 方法。要注意的是这个方法是顺序执行的,在 `.NET 8` 中,可以设置 `HostOption``ServicesStartConcurrently``ServicesStopConcurrently` 方法让启动或者停止并行执行。
57+
58+
```csharp
59+
new HostBuilder()
60+
.ConfigureServices(service =>
61+
{
62+
service.Configure<HostOptions>(options =>
63+
{
64+
options.ServicesStartConcurrently = true;
65+
options.ServicesStopConcurrently = true;
66+
});
67+
service.AddHostedService<FooService>();
68+
service.AddHostedService<BarService>();
69+
})
70+
.Build()
71+
.Run();
72+
73+
internal class FooService : IHostedService
74+
{
75+
public async Task StartAsync(CancellationToken cancellationToken)
76+
{
77+
Console.WriteLine("Start Foo");
78+
await Task.Delay(2000);
79+
}
80+
81+
public async Task StopAsync(CancellationToken cancellationToken)
82+
{
83+
Console.WriteLine("Stop Foo");
84+
await Task.Delay(2000);
85+
}
86+
}
87+
88+
internal class BarService : IHostedService
89+
{
90+
public async Task StartAsync(CancellationToken cancellationToken)
91+
{
92+
Console.WriteLine("Start Bar");
93+
await Task.Delay(1000);
94+
}
95+
96+
public async Task StopAsync(CancellationToken cancellationToken)
97+
{
98+
Console.WriteLine("Stop Bar");
99+
await Task.Delay(1000);
100+
}
101+
}
102+
```
103+
104+
4、[查看 JIT 代码的三种方法](https://www.meziantou.net/how-to-get-assembly-code-generated-by-the-jit-for-a-csharp-method.htm)
105+
106+
C# 支持查看 `JIT` 生成的机器代码,那么该如何查看它们呢?有三种方法
107+
108+
1. DOTNET_JitDisasm="Method"
109+
110+
```csharp
111+
Foo.Bar();
112+
class Foo
113+
{
114+
public static void Bar()
115+
{
116+
Console.WriteLine("Hello World!");
117+
}
118+
}
119+
```
120+
121+
如果设置 `DOTNET_JitDisasm="BAR"` ,那么在执行这个方法的时候,就能看到生成 `JIT` 代码
122+
123+
2. Disasmo
124+
125+
`Disasmo` 是 Visual Studio 的插件,用来查看生成的 JIT 代码。
126+
127+
3. Sharplab
128+
129+
[Sharplab](https://sharplab.io/) 是一个非常有用的 Web 站点,它可以对相关的代码生成相应的 JIT 代码方便查看。
130+
131+
5、[DTO 和 POCO 的区别](https://ardalis.com/dto-or-poco/#sq_hhjrkq9ir7)
132+
133+
![image](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/e2214e4d-d9da-47b1-9ab6-8390bc1a46f4)
134+
135+
`DTO``POCO` 是在开发工程中经常遇到的概念,那么它们区别是怎样的呢?
136+
137+
- DTO
138+
139+
DTO 是 `Data Transfer Object` 的简写,它表明只是传递数据,而不包含逻辑和行为。在 C# 中就是只有只有属性,而不是有方法或者属性的注解。
140+
141+
- POCO
142+
143+
POCO 是 `Plain Old CLR Object` 的简称,它表明这个类不依赖任何第三方的库或者框架。
144+
145+
6、[.NET 最快的 1BRC](https://hotforknowledge.com/2024/01/13/1brc-in-dotnet-among-fastest-on-linux-my-optimization-journey/#results-table)
146+
147+
在今年开始的时候,`GitHub` 爆火了 ”十亿行挑战" 活动。从原先的 `Java` 语言到所有开发语言。在 `.NET` 范围内,目前最快记录是 `1.297` 秒,作者介绍了自己的优化之路。
148+
149+
## 开源项目
150+
151+
1、[NuGet Resolver](https://devblogs.microsoft.com/nuget/introducing-nugetsolver-a-powerful-tool-for-resolving-nuget-dependency-conflicts-in-visual-studio/)
152+
153+
[image](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/0edc9aba-4365-4ae2-939e-4438b8c5d66b)
154+
155+
在一些大型 `.NET` 项目中,常常会遇到依赖冲突的问题,比如
156+
157+
- 无法解析依赖的一致性问题
158+
- 依赖包不包含适合项目的资源包
159+
- 依赖的包版本大于最终解析版本
160+
161+
等等问题,`Nuget` 团队和 MSR 团队合作,推出了 `NuGetSolver``Visual Studio` 插件,它可以解决上述的问题。但是目前有一些限制
162+
163+
1. 只支持 `nuget.org`
164+
2. 不支持多个源
165+
3. 不支持自动更新版本
166+
4. 不支持 preview 版本
167+
5. `package.config` 等老式版本不支持
168+
6. 只支持编译依赖冲突
169+
170+
2、[Rx.NET](https://github.com/dotnet/reactive)
171+
172+
![image](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/2ef55501-fc5d-4081-a80c-26643315fcfd)
173+
174+
`Rx.NET` 是一个开源的 `.NET` 事件库,可以帮助实现响应式编程,这样你的代码只需要响应对应的事件。
175+
176+
```csharp
177+
using System.Reactive.Linq;
178+
179+
IObservable<long> ticks = Observable.Timer(
180+
dueTime: TimeSpan.Zero,
181+
period: TimeSpan.FromSeconds(1));
182+
183+
ticks.Subscribe(tick => Console.WriteLine($"Tick {tick}"));
184+
185+
Console.ReadKey();
186+
```
187+
188+
3、[MSTest Runner](https://devblogs.microsoft.com/dotnet/introducing-ms-test-runner/)
189+
190+
![image](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/9a70f750-b25b-465f-a0a6-fd7998f4b357)
191+
192+
微软推出了 `MSTest Runner` 这个测试框架,它更加轻量级,测试更快并且提供更加便携的测试机制。主要修改两个地方
193+
194+
```xml
195+
<Project Sdk="Microsoft.NET.Sdk">
196+
197+
<PropertyGroup>
198+
<!-- Enable the MSTest runner, this is an opt-in feature -->
199+
<EnableMSTestRunner>true</EnableMSTestRunner>
200+
<!-- We need to produce an executable and not a DLL -->
201+
<OutputType>Exe</OutputType>
202+
</PropertyGroup>
203+
204+
<ItemGroup>
205+
<PackageReference Include="MSTest" Version="3.2.0" />
206+
</ItemGroup>
207+
208+
</Project>
209+
```
210+
211+
这样只需要执行生成的 `exe` 就可以运行单元测试。

0 commit comments

Comments
 (0)