合集-C#8.0核心技术指南[学习笔记]
摘要:IEnumerable 和 IEnumerator IEnumerator接口定义了以向前方式遍历集合的基本底层协议。 声明如下: public interface IEnumerator { bool MoveNext(); object Current { get; } void Reset()
阅读全文
摘要:虽然枚举接口IEnumerable提供了一种向前迭代集合的协议,但是它们并没有提供确定集合大小、根据索引访问成员、搜索以及修改集合的机制。为了实现这些功能,.NET Core定义了ICollection、IList和IDictionary接口。这些接口都支持泛型和非泛型版本。然而,非泛型版本的存在只
阅读全文
摘要:字典是一种集合,其包含的元素均为键值对。字典通常用于查找或用作排序列表。 框架通过IDictionary和IDictionary<TKey, TValue>接口以及一系列通用的字典类定义了标准字典协议。 IDictionary<TKey, TValue> IDictionary<TKey, TVal
阅读全文
摘要:.NET Core提供了一些基本的具体集合类,这些类实现了一系列集合接口。和集合接口一样,每一种集合类型都可以选择使用泛型或非泛型进行实现。在灵活性和性能方面,泛型类更具有优势,而它们的非泛型冗余版本则是为了向后兼容。这与集合接口不同,非泛型集合接口在某些情形下是有其作用的。而泛型List类是最常用
阅读全文
摘要:Array类是所有一维和多维数组的隐式基类,它是实现标准集合接口的最基本类型之一。Array类提供了类型统一性,所以所有的数组对象都能够访问同一套公共方法,而与它们的声明或实际的元素类型无关。 当使用C#语法声明数组时,CLR会将其隐式转换为Array类的子类,合成一个对应该数组维度和元素类型的伪类
阅读全文
摘要:线程是一个可以独立执行的执行路径。 **每一个线程都运行在一个操作系统进程中。**这个进程提供了程序执行的独立环境。 在单线程程序中,进程中只有一个线程运行,因此线程可以独立使用进程环境。而在多线程程序中,一个进程中会运行多个线程。它们共享同一个执行环境(特别是内存)。这在一定程度上说明了多线程的作
阅读全文
摘要:Task是一个更高级的抽象概念,它代表了一个并发操作,而该操作并不一定依赖线程来完成。Task是可以组合的(可以将它们通过延续(continuation)操作串联在一起)。它们可以使用线程池减少启动延迟,也可以通过TaskCompletionSource采用回调的方式避免多个线程同时等待I/O密集型
阅读全文
摘要:1.[ThreadStatic]特性 实现线程本地存储最简单的方式是在静态字段上附加ThreadStatic特性: [ThreadStatic] static int _x; 这样,每个线程都会得到一个_x的独立副本。 但是,[ThreadStatic]并不支持实例字段(它对实例字段并不会产生任何作
阅读全文
摘要:await关键字可以简便地附加延续。 static void Main(string[] args) { DisplayPrimesCount(); } static async void DisplayPrimesCount() { int result = await GetPrimesCoun
阅读全文
摘要:要编写异步函数,可将返回类型void改为Task。这样方法本身就能进行异步调用,并且是可等待的。 async Task PrintAnswerToLife() { await Task.Delay (5000); int answer = 21 * 2; Console.WriteLine (ans
阅读全文
摘要:C#的CLR(即 common language runtime,公共语言运行库)包含两种任务组合器:Task.WhenAny和Task.WhenAll。 我们先定义如下方法: async Task<int> Delay1() { await Task.Delay(1000); return 1;
阅读全文
摘要:在C#8之前,可以使用yield return实现迭代器,也可以用await书写异步函数。但无法两者结合,实现一个可以等待的迭代器。C#8引入了异步流解决了这个问题。 异步流基于以下两个接口。 public interface IAsyncEnumerable<out T> { IAsyncEnum
阅读全文
摘要:排他锁结构有三种:lock语句、Mutex和SpinLock。 **其中lock是最方便最常用的结构。**而其他两种结构多用于处理特定的情形:Mutex可以跨越多个进程(计算机范围锁)。SpinLock可用于实现微优化,可以在高并发场景下减少上下文切换。 lock语句 先看如下代码: class T
阅读全文
摘要:非排他锁目的是限制并发性。 信号量 信号量(semaphore)就像俱乐部一样:它有特定的容量,还有门卫保护。在满员之后,就不允许其他人进入了,人们只能在外面排队。只有当有人离开时,才准许另外一个人进入。信号量的构造器需要至少两个参数:即俱乐部当前的空闲容量以及俱乐部的总容量。 容量为1的信号量与M
阅读全文
摘要:**通过编程发挥多核或多处理器优势的方式称为并行编程。**它是多线程这个更宽泛概念的一个子集。 多线程API和以下可以发挥多核处理器能力的各种结构: 并行LINQ(PLINQ) Parallel类 任务并行结构 并发集合 这些类型一般统称为并行框架(Parallel Framework,PFX)。
阅读全文
摘要:PLINQ可以自动并行化本地LINQ查询。易于使用是PLINQ的优势,因为它将工作划分和结果整理的任务交给了.NET Core。 要使用PLINQ,只需直接在输入序列上调用AsParallel()方法,而后和先前一样编写普通的LINQ查询即可。 例如,以下范例列出了3~100 000之间的所有素数,
阅读全文
摘要:如果需要定期重复执行一些方法,最容易的方式就是使用定时器。相比以下方式,定时器既方便使用又能高效地利用内存和资源。 new Thread(delegate () { while (enabled) { DoSomeAction(); Thread.Sleep(TimeSpan.FromHours(2
阅读全文
摘要:最简单的信号发送结构是事件等待句柄(注意它和C#的事件是无关的)。事件等待句柄有三种实现:AutoResetEvent、ManualResetEvent(Slim)和CountdownEvent。前两种基于通用的EventWaitHandle类,它们继承了基类的所有功能。 AutoResetEven
阅读全文
摘要:.NET Core在System.Collections.Concurrent命名空间下提供了线程安全的集合: | 并发集合 | 非并发等价集合 | | | | | ConcurrentStack<T> | Stack<T> | | ConcurrentQueue<T> | Queue<T> | |
阅读全文
摘要:任务并行是PFX中最底层的并行化方式。相关的类定义在System.Threading.Tasks命名空间,其中包括: Task:管理一个工作单元; Task<TResult>:管理一个带有返回值的工作单元; TaskFactory:创建任务; TaskFactory<TResult>:创建具有指定返
阅读全文