Skip to content

Commit f19854d

Browse files
committed
publish 034
1 parent e501f17 commit f19854d

File tree

12 files changed

+220
-13
lines changed

12 files changed

+220
-13
lines changed

README.md

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

1717
### 2023
1818

19-
**二月份**[033](docs/episode-033.md) :high_brightness:
19+
**二月份**[034](docs/episode-034.md) :high_brightness: | [第 033 期](docs/episode-033.md)
2020

2121
**二月份**[第 032 期](docs/episode-032.md)
2222

docs/episode-007.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ public static void LogInformation(this ILogger logger, string? message, params o
4747

4848
```Csharp
4949
public void Method() {
50-
if (_logger.IsEnable(LogLevel.Infomation)
51-
{
52-
_logger.LogInformation("This is the {0} days", days);
53-
}
50+
if (_logger.IsEnable(LogLevel.Infomation)
51+
{
52+
_logger.LogInformation("This is the {0} days", days);
53+
}
5454
}
5555
```
5656

docs/episode-033.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,35 @@
22

33
## 卷首语
44

5-
之前微软发布了一篇名为 [为什么选择.NET](https://devblogs.microsoft.com/dotnet/why-dotnet/) 的文章作者对它进行了思考
5+
之前微软发布了一篇名为 [为什么选择.NET](https://devblogs.microsoft.com/dotnet/why-dotnet/) 的文章作者对它进行了思考
66

7-
1. 这篇文章是给谁看的
7+
1. 这篇文章的目标读者是谁?
88

9-
这篇文章对于 `.NET` 初学者而言,太复杂了;而对于老手而言,又太简单了。所以这篇文章是那些使用其他的语言,并且对其他编程语言进行评估
9+
这篇文章对于新手来说有些复杂,而对于老手则过于简单。它更适合那些已经在使用其他语言的开发人员对其他编程语言进行评估的人阅读
1010

1111
2. `.NET` 的设计点是什么
1212

13-
原文提出了四个设计点:生产力,性能,安全和可靠性。作者认为最大的地方在于生产力 (Productivity)。最新的 `.NET 7` 对于一个简单的 ASP.NET Core 的应用程序只需要三四行代码
13+
该文章提出了四个设计原则:生产力、性能、安全和可靠性。然而,作者认为最重要的原则是生产力。最新版本的 .NET 7,例如,只需要三到四行代码就可以创建一个简单的 ASP.NET Core 应用程序:
1414

1515
```csharp
1616
var app = WebApplication.Create();
1717
app.MapGet("/", (string? name) => "Hello {name ?? "World"}!");
1818
app.Run();
1919
```
2020

21-
而且现在微软积极的拥抱行业标准,比如 `gPRC``OpenTelemtry` 等等
21+
此外,微软正在积极采用行业标准,例如 gRPCOpenTelemetry 等
2222

23-
3. 它会改变人们的看法吗
23+
3. 这篇文章会改变人们对 .NET 的看法吗?
2424

25-
它只会对那些已经对 `.NET` 感兴趣或者开始考虑使用它的人有作用
25+
这篇文章只会对已经对 .NET 感兴趣或者正在考虑使用它的人有所帮助
2626

2727
## 行业资讯
2828

2929
1、[Visual Studio Extension 升级 .NET 项目](https://devblogs.microsoft.com/dotnet/upgrade-assistant-now-in-visual-studio/)
3030

3131
![image](https://dotnetweeklyimages.blob.core.windows.net/033/dotnetupgrade.png)
3232

33-
微软发布了一款 `Visual Studio` 插件,可以帮助你升级你的 `.NET` 应用程序到最新的版本,同样也支持从 `.NET Framework` 迁移到 `.NET Core` 版本。它支持的类型有
33+
微软发布了一个 Visual Studio 插件,它可以帮助你将 .NET 应用程序升级到最新的版本,也支持从 .NET Framework 迁移到 .NET Core 版本。它支持的类型有
3434

3535
- ASP.NET
3636
- 类库

docs/episode-034.md

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
# .NET 每周分享第 34 期
2+
3+
## 卷首语
4+
5+
上周有人朋友问了一个问题,怎么实现在多线程中使用 `Dictionary`, 最直接想法是使用 `ConcurrentDictionary` 类型。但是这个类太重了, 因为在性能重要的应用场景中,并不是一个很好的选择。如果直接使用 `lock` 方法,又太简单粗暴,因为更多使用场景是多线程读,而不是写。后来就问了一下 `ChatGPT`,看到它又什么建议:
6+
7+
Q: How to use the C# dictionary in in multiple threads?
8+
9+
A:
10+
When using a Dictionary in C# with multiple threads, you need to take into account that Dictionary is not thread-safe by default. This means that if multiple threads try to access or modify the Dictionary concurrently, it may lead to unexpected behavior such as race conditions, deadlocks, or inconsistent results.
11+
To use a Dictionary safely in multiple threads, you can use one of the following approaches:
12+
13+
1. Locking
14+
You can use a lock statement to synchronize access to the Dictionary from multiple threads. This approach ensures that only one thread can access the Dictionary at a time, which eliminates race conditions and ensures consistency.
15+
Here's an example of how to use locking with a Dictionary:
16+
17+
```csharp
18+
Dictionary<string, int> dict = new Dictionary<string, int>();
19+
object dictLock = new object();
20+
// Thread 1
21+
lock (dictLock){
22+
if (!dict.ContainsKey("key")){
23+
dict.Add("key", 1);
24+
}else{
25+
dict["key"]++;
26+
}
27+
}
28+
// Thread 2
29+
lock (dictLock){
30+
if (!dict.ContainsKey("key")){
31+
dict.Add("key", 1);
32+
}else{
33+
dict["key"]++;
34+
}
35+
}
36+
```
37+
38+
2. ConcurrentDictionary: Alternatively, you can use the ConcurrentDictionary class, which is thread-safe by design and allows concurrent access from multiple threads without the need for locking.
39+
40+
Here's an example of how to use a ConcurrentDictionary:
41+
42+
```csharp
43+
ConcurrentDictionary<string, int> dict = new ConcurrentDictionary<string, int>();
44+
// Thread 1
45+
dict.AddOrUpdate("key", 1, (key, value) => value + 1);
46+
// Thread 2
47+
dict.AddOrUpdate("key", 1, (key, value) => value + 1);
48+
```
49+
50+
In this example, the ConcurrentDictionary is accessed by multiple threads using the AddOrUpdate method, which adds a new key-value pair if the key does not exist, or updates the existing value if the key already exists. The ConcurrentDictionary ensures that the updates are atomic and thread-safe, so there is no need for locking.
51+
Overall, the choice of approach depends on the specific requirements and performance considerations of your application. If you have a low number of threads accessing the Dictionary infrequently, the locking approach may be sufficient. However, if you have a high number of threads accessing the Dictionary frequently, the ConcurrentDictionary may be a better option.
52+
53+
看上去不是想要的,继续第二轮提问:
54+
55+
Q: except the ConcurrentDictionary, any else?
56+
57+
A:
58+
59+
Yes, there are a few other thread-safe alternatives to using a ConcurrentDictionary in C#. One such alternative is the ReaderWriterLockSlim class.
60+
The ReaderWriterLockSlim class allows multiple threads to read from a shared resource simultaneously, but only one thread to write to the resource at a time. This can be useful in scenarios where reads are more frequent than writes.
61+
Here's an example of how to use a Dictionary with ReaderWriterLockSlim:
62+
63+
```csharp
64+
Dictionary<string, int> dict = new Dictionary<string, int>();
65+
ReaderWriterLockSlim dictLock = new ReaderWriterLockSlim();
66+
// Thread 1 (Read)
67+
dictLock.EnterReadLock();
68+
int value;
69+
if (dict.TryGetValue("key", out value)){
70+
Console.WriteLine(value);
71+
}
72+
dictLock.ExitReadLock();
73+
// Thread 2 (Write)
74+
dictLock.EnterWriteLock();
75+
if (!dict.ContainsKey("key")){
76+
dict.Add("key", 1);
77+
}else{
78+
dict["key"]++;
79+
}
80+
dictLock.ExitWriteLock();
81+
```
82+
83+
In this example, the ReaderWriterLockSlim object is used to synchronize access to the Dictionary. The EnterReadLock method is called before reading from the Dictionary, and the ExitReadLock method is called after reading is complete. Similarly, the EnterWriteLock method is called before writing to the Dictionary, and the ExitWriteLock method is called after writing is complete.
84+
Overall, the choice of approach depends on the specific requirements and performance considerations of your application. If you have a high number of reads and few writes, the ReaderWriterLockSlim approach may be more performant than using a ConcurrentDictionary. However, if you have a high number of writes, or if you require more complex thread synchronization, a ConcurrentDictionary or other synchronization mechanism may be a better option.
85+
86+
这一次它给出了我之前从来不知道的一个类 `ReaderWriterLockSlim`,而且通过文档查询,它的确满足我们的需求。因此各种 GPT 将来会是软件开发过程中一部分,每当遇到问题的时候,都可以求助它得到更多的提示。
87+
88+
## 行业资讯
89+
90+
1、[Visual Studio 17.5](https://devblogs.microsoft.com/visualstudio/visual-studio-2022-17-5-performance-enhancements/)
91+
92+
Visual Studio 17.5 已经发布,该版本改进了以下几个方面
93+
94+
1. 提高了.NET SDK 等项目的构建速度
95+
2. 支持从外部源进行反编译
96+
3. 更新了线程窗口
97+
4. 改进了 Razor 和 C#编程体验
98+
5. 增加了快速添加功能
99+
6. 支持代码覆盖率统计
100+
101+
2、[Azure Developer - .NET Day](https://devblogs.microsoft.com/dotnet/announcing-azure-developers-dotnet-day/)
102+
103+
![image](https://dotnetweeklyimages.blob.core.windows.net/034/dotnetday.png)
104+
105+
在西雅图时间的 4 月 5 日,微软将主办 .NET 专场的 Azure Developer 活动,届时将有演讲嘉宾出席。
106+
107+
## 文章推荐
108+
109+
1、[Rider 中使用 Git GUI](https://andrewlock.net/working-with-git-in-jetbrains-rider/)
110+
111+
![image](https://dotnetweeklyimages.blob.core.windows.net/034/gitrider.png)
112+
113+
尽管通常情况下人们在命令行中使用 `Git`,但许多集成开发环境(IDE)都集成了 `Git` 的图形用户界面(GUI)操作。在本文中,作者分享了使用 Rider 编辑器时的 Git 使用体验。
114+
115+
2、[.NET 2023 路线图](https://www.youtube.com/watch?v=KCBH1fEIrxc&ab_channel=NickChapsas)
116+
117+
![image](https://dotnetweeklyimages.blob.core.windows.net/034/roadmap.png)
118+
119+
知名博主 `Nick Chapsas` 分享了他的 .NET 2023 年中期路线图。
120+
121+
3、[ChatGPT 4 重构代码](https://www.youtube.com/watch?v=y_NHMGZMb14&ab_channel=NickChapsas)
122+
123+
![image](https://dotnetweeklyimages.blob.core.windows.net/034/refactor.png)
124+
125+
大家都知道 `ChatGPT` 可以协助我们编写代码,而经过进一步升级的 `ChatGPT 4` 在编程方面有了更为显著的进步。在这个视频中,我们让 `ChatGPT 4` 对代码进行了重构,并提出了相应的要求。结果表明,`ChatGPT 4` 在这项任务中表现出色。
126+
127+
4、[.NET 生态发展历程](https://andrewlock.net/understanding-the-dotnet-ecosystem-the-evolution-of-dotnet-into-dotnet-7/)
128+
129+
![image](https://dotnetweeklyimages.blob.core.windows.net/034/dotnethistory.png)
130+
131+
本文探讨了.NET 的发展历程,主要内容包括:
132+
133+
1. 回顾了.NET Framework、Mono 和 Unity 等各种实现,这些实现都有自己的基础库和应用程序模型。
134+
2. 每个平台的基础库都提供了.NET 数据类型,但细微的差异存在。
135+
3. .NET 5 统一了这些平台。
136+
4. .NET 6 则统一了运行时和工具链。
137+
5. .NET 每年都会发布新版本,并将其分为长期支持版本(LTS)和短期支持版本(STS)。
138+
139+
5、[async & await 是如何工作的](https://devblogs.microsoft.com/dotnet/how-async-await-really-works/)
140+
141+
这是一篇来自 `Stephen Toub` 的长文,他介绍整个 `.NET` 异步的历史和 `async``await` 的发展历程,非常值得一读。
142+
143+
## 开源项目
144+
145+
1、[ChatGPT .NET SDK](https://github.com/marcominerva/ChatGptNet)
146+
147+
![image](https://dotnetweeklyimages.blob.core.windows.net/034/sdk.png)
148+
149+
ChatGPT 是目前备受瞩目的技术创新,而且随着 OpenAPI 开放 WebAPI 接口,各行各业都可以利用 ChatGPT 来提高生产力。ChatGptNET 是一个开源库,将 WebAPI 封装成 SDK,为大家提供了更便捷的接入方式。
150+
151+
2、[FluentValidation](https://github.com/FluentValidation/FluentValidation)
152+
153+
![image](https://dotnetweeklyimages.blob.core.windows.net/034/validator.png)
154+
155+
FluentValidation 是一个开源的 `C#` 验证库,它可以验证某个对象事否满足要求。
156+
157+
```csharp
158+
public class CustomerValidator : AbstractValidator<Customer>
159+
{
160+
public CustomerValidator()
161+
{
162+
RuleFor(x => x.Surname).NotEmpty();
163+
RuleFor(x => x.Forename).NotEmpty().WithMessage("Please specify a first name");
164+
RuleFor(x => x.Discount).NotEqual(0).When(x => x.HasDiscount);
165+
RuleFor(x => x.Address).Length(20, 250);
166+
RuleFor(x => x.PostCode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");
167+
}
168+
private bool BeAValidPostcode(string postcode)
169+
{
170+
//....
171+
return true;
172+
}
173+
}
174+
175+
public class Customer
176+
{
177+
public string Surname { get; set; }
178+
public string Forename { get; set; }
179+
public double Discount { get; set; }
180+
public string Address { get; set; }
181+
public string PostCode { get; set; }
182+
public bool HasDiscount { get; set; }
183+
}
184+
```
185+
186+
调用 `Validate` 方法可以得到验证的结果
187+
188+
```csharp
189+
var customer = new Customer();
190+
var validator = new CustomerValidator();
191+
ValidationResult results = validator.Validate(customer);
192+
Console.WriteLine(results.IsValid);
193+
results.Errors.ForEach(Console.WriteLine);
194+
```
195+
196+
3、[CSharpREPL](https://github.com/waf/CSharpRepl)
197+
198+
![image](https://dotnetweeklyimages.blob.core.windows.net/034/repl.png)
199+
200+
`CSharpRepl` 时一个开源的 `C#` 的 REPL,它有一下的功能
201+
202+
1. 智能提示
203+
2. 主题管理
204+
3. 添加引用
205+
- 动态库 `#r "AssemblyName"`
206+
- 其他项目 `#r "path/to/projects.csproj"`
207+
- Nuget 包 `# "nuget: package"`

docs/images/034/dotnetday.png

598 KB
Loading

docs/images/034/dotnethistory.png

30.5 KB
Loading

docs/images/034/gitrider.png

759 KB
Loading

docs/images/034/refactor.png

606 KB
Loading

docs/images/034/repl.png

65.5 KB
Loading

docs/images/034/roadmap.png

923 KB
Loading

0 commit comments

Comments
 (0)