0

0

C#并发编程·经典实例读书笔记

黄舟

黄舟

发布时间:2017-02-06 16:43:46

|

1569人浏览过

|

来源于php中文网

原创

前言

最近在看《C# 并发编程 · 经典实例》这本书,这不是一本理论书,反而这是一本主要讲述怎么样更好的使用好目前 C#.NET 为我们提供的这些 API 的一本书,书中绝大部分是一些实例,在日常开发中还是经常会使用到。

书中一些观点还是比较赞同,比如作者说目前绝大多数的图书对关于并发多线程等这些内容放到最后,而缺少一本介绍并发编程的入门指引和参考。

另外一个观点是绝大多数国内的技术人员认为技术越底层就牛逼,而做上层应用的就是“码农”,作者反对了这一观点,其实能利用好现有的库也是一种能力,虽然说理解基础知识对日常生活仍然有帮助,但最好从更高级的抽象概念来学习。

异步基础

任务暂停,休眠

异步方式暂停或者休眠任务,可以使用 Task.Delay();

static async Task DelayResult(T result, TimeSpan delay) {
    await Task.Delay(delay);
    return result;
}

异步重试机制

一个简单的指数退避策略,重试的时间会逐次增加,在访问 Web 服务时,一般采用此种策略。

static async Task DownloadString(string uri) {
    using (var client = new HttpClient()) {
        var nextDealy = TimeSpan.FromSeconds(1);
        for (int i = 0; i != 3; ++i) {
            try {
                return await client.GetStringAsync(uri);
            }
            catch {
            }
            await Task.Delay(nextDealy);
            nextDealy = nextDealy + nextDealy;
        }
        //最后重试一次,抛出出错信息           
        return await client.GetStringAsync(uri);
    }
}

报告进度

异步操作中,经常需要展示操作进度,可以使用 IProcess 和 Process

static async Task MyMethodAsync(IProgress progress) {
    double precentComplete = 0;
    bool done = false;
    while (!done) {
        await Task.Delay(100);
        if (progress != null) {
            progress.Report(precentComplete);
        }
        precentComplete++;
        if (precentComplete == 100) {
            done = true;
        }
    }
}
public static void Main(string[] args) {
    Console.WriteLine("starting...");
    var progress = new Progress();
    progress.ProgressChanged += (sender, e) => {
        Console.WriteLine(e);
    };
    MyMethodAsync(progress).Wait();
    Console.WriteLine("finished");
}

等待一组任务

同时执行几个任务,等待他们全部完成

Task task1 = Task.Delay(TimeSpan.FromSeconds(1));
Task task2 = Task.Delay(TimeSpan.FromSeconds(2));
Task task3 = Task.Delay(TimeSpan.FromSeconds(1));
Task.WhenAll(task1, task2, task3).Wait();

等待任意一个任务完成

执行若干任务,只需要对其中一个的完成进行响应。主要用于对一个操作进行多种独立的尝试,只要其中一个尝试完成,任务就算完成。

static async Task FirstResponseUrlAsync(string urlA, string urlB) {
    var httpClient = new HttpClient();
    Task downloadTaskA = httpClient.GetByteArrayAsync(urlA);
    Task downloadTaskB = httpClient.GetByteArrayAsync(urlB);
    Task completedTask = await Task.WhenAny(downloadTaskA, downloadTaskB);
    byte[] data = await completedTask;
    return data.Length;
}

集合

不可变栈和队列

需要一个不会经常修改,可以被多个线程安全访问的栈和队列。他们的API和 Stack 和 Queue 非常相似。性能上,不可变栈(LIFO)和队列(FIFO)与标准的栈和队列具有相同的时间复杂度。但是在需要频繁修改的简单情况下,标准栈和队列速度更快。

在内部实现上,当对一个对象进行覆盖(重新赋值)的时候,不可变集合采用的是返回一个修改过的集合,原始集合引用是不变化的,也就是说如果另外一个变量引用了相同的对象,那么它(另外的变量)是不会变化的。

ImmutableStack

var stack = ImmutableStack.Empty;
stack = stack.Push(11);  
var biggerstack = stack.Push(12);
foreach (var item in biggerstack) {
    Console.WriteLine(item);
}  // output: 12 11
int lastItem;
stack = stack.Pop(out lastItem);
Console.WriteLine(lastItem);  //output: 11

实际上,两个栈内部共享了存储 11 的内存,这种实现方式效率很高,而且每个实例都是线程安全的。

初阶PHP Apache MySQL网站设计
初阶PHP Apache MySQL网站设计

初阶PHP Apache MySQL网站设计来自作者多年学习、应用和讲授PHP的经验与体会,是专为学习PHP+MySQL数据库编程人员编与的入门教材。在最后二章设计了2个贴近实际应用的典型案例:留言本系统和论坛系统,每个案例先介绍开发思路、步骤,再给出全部源代码,使所学内容与实际应用紧密结合,特别是论坛系统将全书的案例串讲起来,力求使读者学到最贴近应用前沿的知识和技能。

下载

ImmutableQueue

var queue = ImmutableQueue.Empty;
queue = queue.Enqueue(11);
queue = queue.Enqueue(12);
foreach (var item in queue) {
    Console.WriteLine(item);
} // output: 11  12
int nextItem;
queue = queue.Dequeue(out nextItem);
Console.WriteLine(nextItem); //output: 11

不可变列表和集合

ImmutableList

时间复杂度

911.jpg

有些时候需要这样一个数据结构:支持索引,不经常修改,可以被多线程安全的访问。

var list = ImmutableList.Empty;
list = list.Insert(0, 11);
list = list.Insert(0, 12);
foreach (var item in list) {
    Console.WriteLine(item);
} // 12 11

ImmutableList 可以索引,但是注意性能问题,不能用它来简单的替代 List。它的内部实现是用的二叉树组织的数据,这么做是为了让不同的实例之间共享内存。

ImmutableHashSet

有些时候需要这样一个数据结构:不需要存放重复内容,不经常修改,可以被多个线程安全访问。时间复杂度 O(log N)。

var set = ImmutableHashSet.Empty;
set = set.Add(11);
set = set.Add(12);
foreach (var item in set) {
    Console.WriteLine(item);
} // 11 12 顺序不定

线程安全字典

一个线程安全的键值对集合,多个线程读写仍然能保持同步。

ConcurrentDictionary

混合使用了细粒度的锁定和无锁技术,它是最实用的集合类型之一。

var dictionary = new ConcurrentDictionary();
dictionary.AddOrUpdate(0, key => "Zero", (key, oldValue) => "Zero");

如果多个线程读写一个共享集合,实用 ConcurrentDictionary 是最合适的。如果不会频繁修改,那么更适合使用 ImmutableDictionary

它最适合用于在需要共享数据的场合,即多个线程共享一个集合,如果一些线程只添加元素一些线程只移除元素,那最好使用 生产者/消费者集合(BlockingCollection)。

初始化共享资源

程序多个地方使用一个值,第一次访问时对它进行初始化。

static int _simpleVluae;
static readonly Lazy> shardAsyncInteger =
    new Lazy>(async () => {
        await Task.Delay(2000).ConfigureAwait(false);
        return _simpleVluae++;
    });
public static void Main(string[] args) {

    int shareValue = shardAsyncInteger.Value.Result;
    Console.WriteLine(shareValue); // 0
    shareValue = shardAsyncInteger.Value.Result;
    Console.WriteLine(shareValue); // 0
    shareValue = shardAsyncInteger.Value.Result;
    Console.WriteLine(shareValue); // 0
}

以上就是C#并发编程·经典实例读书笔记的内容,更多相关内容请关注PHP中文网(www.php.cn)!

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

14

2026.01.30

c++ 字符串格式化
c++ 字符串格式化

本专题整合了c++字符串格式化用法、输出技巧、实践等等内容,阅读专题下面的文章了解更多详细内容。

9

2026.01.30

java 字符串格式化
java 字符串格式化

本专题整合了java如何进行字符串格式化相关教程、使用解析、方法详解等等内容。阅读专题下面的文章了解更多详细教程。

12

2026.01.30

python 字符串格式化
python 字符串格式化

本专题整合了python字符串格式化教程、实践、方法、进阶等等相关内容,阅读专题下面的文章了解更多详细操作。

4

2026.01.30

java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

20

2026.01.29

java配置环境变量教程合集
java配置环境变量教程合集

本专题整合了java配置环境变量设置、步骤、安装jdk、避免冲突等等相关内容,阅读专题下面的文章了解更多详细操作。

18

2026.01.29

java成品学习网站推荐大全
java成品学习网站推荐大全

本专题整合了java成品网站、在线成品网站源码、源码入口等等相关内容,阅读专题下面的文章了解更多详细推荐内容。

19

2026.01.29

Java字符串处理使用教程合集
Java字符串处理使用教程合集

本专题整合了Java字符串截取、处理、使用、实战等等教程内容,阅读专题下面的文章了解详细操作教程。

3

2026.01.29

Java空对象相关教程合集
Java空对象相关教程合集

本专题整合了Java空对象相关教程,阅读专题下面的文章了解更多详细内容。

6

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 8万人学习

C 教程
C 教程

共75课时 | 4.3万人学习

C++教程
C++教程

共115课时 | 14.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号