更新记录

本文迁移自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();
}
}
}

最新文章

  1. 如何优雅的使用RabbitMQ
  2. 第二章 --- 关于Javascript 设计模式 之 策略模式
  3. 30 algorithm questions study
  4. 【python】入门学习(六)
  5. CCEA OCX
  6. 为EasyUI 的Tab 标签添加右键菜单
  7. Js组件的一些写法【转】
  8. Python存取XML方法简介
  9. shell小技巧
  10. Gerrit 删除项目
  11. MVC Razor 一些常用的方法
  12. PCB外形加工培训教材
  13. navicat重新系统丢失libmysql_e
  14. HttpStatus各种状态
  15. java设计模式---三种工厂模式之间的区别
  16. Google 浏览器好用插件推荐
  17. 十分钟通过 NPM 创建一个命令行工具
  18. Linux查找文件内容
  19. linux系统编程之文件与IO(五):stat()系统调用获取文件信息
  20. frame shiro 认证示例及原理简述

热门文章

  1. findmnt、lsblk、mount 命令查看磁盘、目录挂载、挂载点以及文件系统格式等情况
  2. 帝国CMS灵动标签调用相关文章
  3. 1903021116-吉琛-Java第四周作业-程序编写
  4. python中常用内置函数和关键词
  5. Glade To Code 介绍
  6. Exception in thread &quot;main&quot; java.awt.AWTError: Assistive Technology not found: org.GNOME.Accessibilit
  7. netty系列之:netty中的核心解码器json
  8. XCTF练习题---MISC---Recover-Deleted-File
  9. 抽象类 &amp; 接口
  10. Django与socket