.NET中的并发操作集合
2024-09-07 10:44:16
更新记录
本文迁移自Panda666原博客,原发布时间:2021年7月1日。
一、并发集合
.NET中提供了相当多线程安全的集合,它们都在System.Collections.Concurrent命名空间下。具体的类型进行可以到.NET官方API浏览器:点击这里访问查看。
具体类型如下:
二、多任务写入/读取ConcurrentQueue
这里使用支持并发的队列ConcurrentQueue作为例子,通过2个Task进行进队任务,再通过2个Task进行出队的任务。
using System;
using System.Threading.Tasks;
using System.Collections.Concurrent;
namespace PadnaTestClass
{
class Program
{
static void Main(string[] args)
{
//用于写入的集合
ConcurrentQueue<string> concurrentQueue = new ConcurrentQueue<string>();
//=========================进队操作==========================
//新建进队任务1
Task taskForEnqueue1 = Task.Run(() => {
for (int i = 0; i <= 10000; i++)
{
//存入和输出的内容
string content = $"进队任务1,当前执行到{i}";
//进队
concurrentQueue.Enqueue(content);
//输出操作过程
Console.WriteLine(content);
}
});
//新建进队任务2
Task taskForEnqueue2 = Task.Run(() => {
for (int i = 0; i <= 10000; i++)
{
//存入和输出的内容
string content = $"进队任务2,当前执行到{i}";
//进队
concurrentQueue.Enqueue(content);
//输出操作过程
Console.WriteLine(content);
}
});
//等待写入任务完成
Task.WaitAll(new Task[] { taskForEnqueue1, taskForEnqueue2 });
//=========================进队操作==========================
//=========================出队操作===================
//新建出队任务1
Task taskForDequeue1 = Task.Run(() => {
while (concurrentQueue.Count != 0)
{
if (concurrentQueue.TryDequeue(out string result))
{
Console.WriteLine("出队任务1-" + result);
}
}
});
//新建出队任务2
Task taskForDequeue2 = Task.Run(() => {
while (concurrentQueue.Count != 0)
{
if (concurrentQueue.TryDequeue(out string result))
{
Console.WriteLine("出队任务2-" + result);
}
}
});
//=========================出队操作====================
//wait
Console.ReadKey();
}
}
}
```
### 三、多任务写入/读取ConcurrentDictionary
这里使用支持并发的字典ConcurrentDictionary作为例子,通过2个Task进行写入元素数据任务,再通过2个Task进行读取和移除元素的任务。
```c#
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Collections.Concurrent;
namespace PadnaTestClass
{
class Program
{
static void Main(string[] args)
{
//用于写入的集合
ConcurrentDictionary<string,string> concurrentDictionary = new ConcurrentDictionary<string,string>();
//==========添加数据操作=================
//新建用于写入数据的任务1
Task taskForAddData1 = Task.Run(() => {
for (int i = 0; i <= 10000; i++)
{
//存入和输出的内容
string dataKey = $"任务1的-{i}-Key";
string dataValue = $"任务1的-{i}-Value";
//加入数据到并发集合中
concurrentDictionary.TryAdd(dataKey, dataValue);
//输出操作过程
Console.WriteLine(dataKey + " || " + dataValue);
}
});
//新建用于写入数据的任务2
Task taskForAddData2 = Task.Run(() => {
for (int i = 0; i <= 10000; i++)
{
//存入和输出的内容
string dataKey = $"任务2的-{i}-Key";
string dataValue = $"任务2的-{i}-Value";
//加入数据到并发集合中
concurrentDictionary.TryAdd(dataKey, dataValue);
//输出操作过程
Console.WriteLine(dataKey + " || " + dataValue);
}
});
//等待写入任务完成
Task.WaitAll(new Task[] { taskForAddData1, taskForAddData2 });
//==============添加数据操作=================
//=============读取并移除数据操作============
//新建读取并删除元素任务1
Task taskForReadData1 = Task.Run(() => {
foreach (string dataKey in concurrentDictionary.Keys)
{
if (concurrentDictionary.TryGetValue(dataKey, out string dataValue))
{
//输出值
Console.WriteLine(dataValue);
//移除值
concurrentDictionary.TryRemove(new KeyValuePair<string, string>(dataKey,dataValue));
}
}
});
//新建读取并删除元素任务2
Task taskForReadData2 = Task.Run(() => {
foreach (string dataKey in concurrentDictionary.Keys)
{
if (concurrentDictionary.TryGetValue(dataKey, out string dataValue))
{
//输出值
Console.WriteLine(dataValue);
//移除值
concurrentDictionary.TryRemove(new KeyValuePair<string, string>(dataKey, dataValue));
}
}
});
//==========读取并移除数据操作=========
//等待任务完成
Task.WaitAll(taskForReadData1, taskForReadData2);
//读取集合元素的个数
Console.WriteLine(concurrentDictionary.Count); //0
//wait
Console.ReadKey();
}
}
}
最新文章
- 如何优雅的使用RabbitMQ
- 第二章 --- 关于Javascript 设计模式 之 策略模式
- 30 algorithm questions study
- 【python】入门学习(六)
- CCEA OCX
- 为EasyUI 的Tab 标签添加右键菜单
- Js组件的一些写法【转】
- Python存取XML方法简介
- shell小技巧
- Gerrit 删除项目
- MVC Razor 一些常用的方法
- PCB外形加工培训教材
- navicat重新系统丢失libmysql_e
- HttpStatus各种状态
- java设计模式---三种工厂模式之间的区别
- Google 浏览器好用插件推荐
- 十分钟通过 NPM 创建一个命令行工具
- Linux查找文件内容
- linux系统编程之文件与IO(五):stat()系统调用获取文件信息
- frame shiro 认证示例及原理简述
热门文章
- findmnt、lsblk、mount 命令查看磁盘、目录挂载、挂载点以及文件系统格式等情况
- 帝国CMS灵动标签调用相关文章
- 1903021116-吉琛-Java第四周作业-程序编写
- python中常用内置函数和关键词
- Glade To Code 介绍
- Exception in thread ";main"; java.awt.AWTError: Assistive Technology not found: org.GNOME.Accessibilit
- netty系列之:netty中的核心解码器json
- XCTF练习题---MISC---Recover-Deleted-File
- 抽象类 &; 接口
- Django与socket