当前位置:网站首页>为什么有的人把代码写的如此复杂?
为什么有的人把代码写的如此复杂?
2022-07-22 22:03:00 【格格巫 MMQ!!】
技术群里有人发了一段代码:
附言:兄弟们,这个单例怎么样?
我回复:什么鬼,看不懂啊?!
也有其他小伙伴表示看不懂,看来大家的C#基础和我一样并不全面。
我看不懂,主要是因为我没用过TaskCompletionSource和Interlocked的CompareExchange方法,然后经过我1、2个小时的研究,终于勉强看懂了。
由于上面这段代码只贴了一张图,我没有拿到源码,所以我写了个差不多的Demo用于测试,代码如下:
复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SingletonTest
{
public class Singleton
{
private static Task _stringTask;
/// <summary>
/// 重置,方便重复测试
/// </summary>
public void Reset()
{
_stringTask = null;
}
public Task<string> InitAsync()
{
if (_stringTask != null)
{
return _stringTask;
}
var inition = new TaskCompletionSource<string>(TaskCreationOptions.RunContinuationsAsynchronously);
var initonTask = Interlocked.CompareExchange(ref _stringTask, inition.Task, null);
if (initonTask != null)
{
return initonTask;
}
_stringTask = CreateContent(inition);
return inition.Task;
}
private async Task<string> CreateContent(TaskCompletionSource<string> inition)
{
string content = await TextUtil.GetTextAsync();
inition.SetResult(content);
return content;
}
}
}
复制代码
然后按照我自己的习惯,又写了一版:
复制代码
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SingletonTest
{
class Singleton2
{
private static string _value;
private SemaphoreSlim _semaphoreSlim = new SemaphoreSlim(1, 1);
/// <summary>
/// 重置,方便重复测试
/// </summary>
public void Reset()
{
_value = null;
}
public async Task<string> InitAsync()
{
if (_value != null)
{
return _value;
}
await _semaphoreSlim.WaitAsync();
if (_value == null)
{
_value = await TextUtil.GetTextAsync();
}
_semaphoreSlim.Release();
return _value;
}
}
}
复制代码
很容易懂,不是吗?
这段代码我好像是理解了,可是我不理解的是,为什么代码会写的这么复杂呢?
最主要的是我不理解下面几行:
复制代码
var inition = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
var initonTask = Interlocked.CompareExchange(ref _stringTask, inition.Task, null);
if (initonTask != null)
{
return initonTask;
}
复制代码
我要给它翻译成我能理解的代码,我意思到new的TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously)也是个单例,所以我先写了个TaskCompletionSourceFactory类:
复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SingletonTest
{
public class TaskCompletionSourceFactory : IDisposable
{
private TaskCompletionSource _value;
private TaskCompletionSourceData _data;
private SemaphoreSlim _semaphoreSlim = new SemaphoreSlim(1, 1);
public TaskCompletionSourceData Instance
{
get
{
_semaphoreSlim.Wait();
if (_value == null)
{
_data = new TaskCompletionSourceData();
_value = new TaskCompletionSource<string>(TaskCreationOptions.RunContinuationsAsynchronously);
_data.Value = _value;
_data.First = true;
}
else
{
_data = new TaskCompletionSourceData();
_data.Value = _value;
_data.First = false;
}
_semaphoreSlim.Release();
return _data;
}
}
public void Dispose()
{
_semaphoreSlim.Dispose();
}
}
public class TaskCompletionSourceData
{
public bool First { get; set; }
public TaskCompletionSource<string> Value { get; set; }
}
}
复制代码
然后把Demo中Singleton这个类改写了一下:
复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SingletonTest
{
public class Singleton3
{
private static Task _stringTask;
/// <summary>
/// 重置,方便重复测试
/// </summary>
public void Reset()
{
_stringTask = null;
}
public Task<string> InitAsync(TaskCompletionSourceFactory factory)
{
if (_stringTask != null)
{
return _stringTask;
}
var inition = factory.Instance;
if (!inition.First)
{
return inition.Value.Task;
}
_stringTask = CreateContent(inition.Value);
return inition.Value.Task;
}
private async Task<string> CreateContent(TaskCompletionSource<string> inition)
{
string content = await TextUtil.GetTextAsync();
inition.SetResult(content);
return content;
}
}
}
复制代码
当我差不多理解了之后,我发现原始代码有一点点小问题,就是TaskCompletionSource是有机率被重复new的。
大家觉得哪种写法好呢?
附:
TextUtil.cs代码,是一个模拟获取文本的方法:
复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SingletonTest
{
public class TextUtil
{
public static Task GetTextAsync()
{
return Task.Run(() =>
{
Thread.Sleep(10);
Random rnd = new Random();
return rnd.Next(0, 1000).ToString().PadRight(10);
});
}
}
}
复制代码
测试代码:
复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SingletonTest
{
class Program
{
private static int _count = 200;
private static Singleton _singleton = new Singleton();
private static Singleton2 _singleton2 = new Singleton2();
private static Singleton3 _singleton3 = new Singleton3();
static void Main(string[] args)
{
ThreadPool.SetMinThreads(20, 20);
Task.Run(() => { }); //Task预热
Console.WriteLine("输入1测试Singleton,输入2测试Singleton2,如果值都相同,说明单例测试通过,否则不通过");
while (true)
{
var key = Console.ReadKey().Key;
if (key == ConsoleKey.D1)
{
Console.WriteLine("测试Singleton");
Test();
}
if (key == ConsoleKey.D2)
{
Console.WriteLine("测试Singleton2");
Test2();
}
if (key == ConsoleKey.D3)
{
Console.WriteLine("测试Singleton3");
Test3();
}
}
}
public static void Test()
{
List<Task> taskList = new List<Task>();
for (int i = 0; i < _count; i++)
{
Task task = Task.Run(async () =>
{
string content = await _singleton.InitAsync();
Console.Write(content);
});
taskList.Add(task);
}
Task.WaitAll(taskList.ToArray());
_singleton.Reset();
Console.WriteLine("");
}
public static void Test2()
{
List<Task> taskList = new List<Task>();
for (int i = 0; i < _count; i++)
{
Task task = Task.Run(async () =>
{
string content = await _singleton2.InitAsync();
Console.Write(content);
});
taskList.Add(task);
}
Task.WaitAll(taskList.ToArray());
_singleton2.Reset();
Console.WriteLine("");
}
public static void Test3()
{
TaskCompletionSourceFactory factory = new TaskCompletionSourceFactory();
List<Task> taskList = new List<Task>();
for (int i = 0; i < _count; i++)
{
Task task = Task.Run(async () =>
{
string content = await _singleton3.InitAsync(factory);
Console.Write(content);
});
taskList.Add(task);
}
Task.WaitAll(taskList.ToArray());
_singleton3.Reset();
factory.Dispose();
Console.WriteLine("");
}
}
}
边栏推荐
- Scala main constructor_ Scala main constructor depth
- Dispersion tensor analysis open source software DSI studio simplified Chinese version can be downloaded
- 算法面试高频题解指南【一】
- Organizational structure of agile testing team
- Qt+VTK+PCL图片转灰度图且以灰度为Y轴显示
- Building a sylixos environment in VMWare
- ProSci LAG3抗体:改善体外研究,助力癌症免疫治疗
- Codeforces round 809 (Div. 2) (Questions C and D1)
- 图的存储结构及方法(一)
- 初出茅庐的小李第109篇博客之如何打开Keil中文件的真是路径
猜你喜欢

大咖访谈 | 开源社区里各种奇怪的现状——夜天之书陈梓立tison

学习总结 | 真实记录 MindSpore 两日集训营能带给你什么(一)!

Qt+VTK+PCL图片转灰度图且以灰度为Y轴显示

树以及二叉树的常用性质以及遍历

@Transactional transaction methods contain multiple transaction methods of the same kind. These transaction methods themselves are set to fail. There are two solutions

实验六 MPEG
![Reading notes - > statistics] construction of 12-02 confidence interval -t distribution concept introduction](/img/4d/25b4d3d6af0fb30c222613d3c428b7.png)
Reading notes - > statistics] construction of 12-02 confidence interval -t distribution concept introduction

不会吧?钉钉都下载了,你还不知道可以这样玩?

matlab声音信号处理 频率图 信号过滤和播放声音

多商户系统的直播功能用过吗?用过的朋友扣个 666!
随机推荐
pycharm中使用私钥远程连接服务器
Three effective strategies for driving page performance optimization
VMware virtual machine changes static IP and reports an error unit network Service entered failed state solution
The Chinese and English dot matrix character display principle of the 111th blog of the fledgling Xiao Li
Fastapi learning (II) -- fastapi+jinjia2 template rendering web page (jump back to the rendering page)
实验二 YUV
Jmeter查看结果树之查看响应的13种详解方法!
Detailed analysis of the 110th blog of the fledgling Xiao Li in stm32__ NVIC_ Setprioritygrouping (uint32_t prioritygroup) function
实验五 JPEG
21 -- product of arrays other than itself
读书笔记->统计学】12-02 置信区间的构建-t分布概念简介
networkx 对图进行可视化
高精度移相(MCP41xx)程序stm32F103,F407通用,更改引脚即可(SPI软件模拟通信)
text-align:center居中
Scala learning -- six uses of generics [t]
Hcip --- BGP comprehensive experiment
老板要我做一个 IP 属地功能,一个开源库搞定!
Yolov5 post-processing code of cpu/gpu (CUDA) version
php可不可以拆分数组
开发者分享|『啃书吧:深度学习与MindSpore实践』第一章