如何在.Net中实现ConcurrentHashSet

2024-03-02

我正在尝试本着 ConcurrentDictionary 的精神实现 ConcurrentHashSet, 采取的方法是使用内部支持 ConcurrentDictionary 并编写小型委托方法,这就是我所取得的进展,但是我坚持使用集合理论方法,尤其是。我不确定是否可以使用 foreach 并且仍然不违反并发性

public class ConcurrentHashSet<TElement> : ISet<TElement>
{
    private readonly ConcurrentDictionary<TElement, object> _internal;

    public ConcurrentHashSet(IEnumerable<TElement> elements = null)
    {
        _internal = new ConcurrentDictionary<TElement, object>();
        if (elements != null)
            UnionWith(elements);
    }

    public void UnionWith(IEnumerable<TElement> other)
    {
        if (other == null) throw new ArgumentNullException("other");

        foreach (var otherElement in other)
            Add(otherElement);
    }

    public void IntersectWith(IEnumerable<TElement> other)
    {
        throw new NotImplementedException();
    }

    public void ExceptWith(IEnumerable<TElement> other)
    {
        throw new NotImplementedException();
    }

    public void SymmetricExceptWith(IEnumerable<TElement> other)
    {
        throw new NotImplementedException();
    }

    public bool IsSubsetOf(IEnumerable<TElement> other)
    {
        throw new NotImplementedException();
    }

    public bool IsSupersetOf(IEnumerable<TElement> other)
    {
        throw new NotImplementedException();
    }

    public bool IsProperSupersetOf(IEnumerable<TElement> other)
    {
        throw new NotImplementedException();
    }

    public bool IsProperSubsetOf(IEnumerable<TElement> other)
    {
        throw new NotImplementedException();
    }

    public bool Overlaps(IEnumerable<TElement> other)
    {
        return other.Any(otherElement => _internal.ContainsKey(otherElement));
    }

    public bool SetEquals(IEnumerable<TElement> other)
    {
        int otherCount = 0;
        int thisCount = Count;
        foreach (var otherElement in other)
        {
            otherCount++;
            if (!_internal.ContainsKey(otherElement))
                return false;
        }
        return otherCount == thisCount;
    }

    public bool Add(TElement item)
    {
        return _internal.TryAdd(item, null);
    }

    public void Clear()
    {
        _internal.Clear();
    }

    // I am not sure here if that fullfills contract correctly
    void ICollection<TElement>.Add(TElement item)
    {
        Add(item);
    }

    public bool Contains(TElement item)
    {
        return _internal.ContainsKey(item);
    }

    public void CopyTo(TElement[] array, int arrayIndex)
    {
        _internal.Keys.CopyTo(array, arrayIndex);
    }

    public bool Remove(TElement item)
    {
        object ignore;
        return _internal.TryRemove(item, out ignore);
    }

    public int Count
    {
        get { return _internal.Count; }
    }

    public bool IsReadOnly
    {
        get { return false; }
    }

    public IEnumerator<TElement> GetEnumerator()
    {
        return _internal.Keys.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

我刚刚遇到了类似的场景(“我对快速添加、包含和删除感兴趣”)并实现了这个傻瓜:

using System.Collections.Generic;
using System.Threading;

namespace BlahBlah.Utilities
{
    public class ConcurrentHashSet<T> : IDisposable
    {
        private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
        private readonly HashSet<T> _hashSet = new HashSet<T>();

        #region Implementation of ICollection<T> ...ish
        public bool Add(T item)
        {
            try
            {
                _lock.EnterWriteLock();
                return _hashSet.Add(item);
            }
            finally
            {
                if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
            }
        }

        public void Clear()
        {
            try
            {
                _lock.EnterWriteLock();
                _hashSet.Clear();
            }
            finally
            {
                if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
            }
        }

        public bool Contains(T item)
        {
            try
            {
                _lock.EnterReadLock();
                return _hashSet.Contains(item);
            }
            finally
            {
                if (_lock.IsReadLockHeld) _lock.ExitReadLock();
            }
        }

        public bool Remove(T item)
        {
            try
            {
                _lock.EnterWriteLock();
                return _hashSet.Remove(item);
            }
            finally
            {
                if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
            }
        }

        public int Count
        {
            get
            {
                try
                {
                    _lock.EnterReadLock();
                    return _hashSet.Count;
                }
                finally
                {
                    if (_lock.IsReadLockHeld) _lock.ExitReadLock();
                }
            }
        }
        #endregion

        #region Dispose
        public void Dispose()
        {
            if (_lock != null) _lock.Dispose();
        }
        #endregion
    }
}

还没有真正测试过它(性能或可靠性方面)。 YMMV。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在.Net中实现ConcurrentHashSet 的相关文章

  • C free() 是如何工作的? [复制]

    这个问题在这里已经有答案了 可能的重复 malloc 和 free 如何工作 https stackoverflow com questions 1119134 how malloc and free work include
  • XPATH 查询、HtmlAgilityPack 和提取文本

    我一直在尝试从名为 tim new 的类中提取链接 我也得到了解决方案 给出了解决方案 片段和必要的信息here https stackoverflow com questions 2982862 extracting a table ro
  • 异常堆栈跟踪不显示抛出异常的位置

    通常 当我抛出异常 捕获它并打印出堆栈跟踪时 我会看到抛出异常的调用 导致该异常的调用 导致该异常的调用that 依此类推回到整个程序的根 现在它只向我显示异常所在的调用caught 而不是它所在的地方thrown 我不明白是什么改变导致了
  • 如果 JSON.NET 中的值为 null 或空格,则防止序列化

    我有一个对象需要以这样的方式序列化 即 null 和 空白 空或只是空格 值都不会序列化 我不控制对象本身 因此无法设置属性 但我知道所有属性都是字符串 环境NullValueHandling显然 忽略 只能让我找到解决方案的一部分 它 似
  • 将 OpenCV Mat 转换为数组(可能是 NSArray)

    我的 C C 技能很生疏 OpenCV 的文档也相当晦涩难懂 有没有办法获得cv Mat data属性转换为数组 NSArray 我想将其序列化为 JSON 我知道我可以使用 FileStorage 实用程序转换为 YAML XML 但这不
  • while循环中的变量初始化

    我有一个可以分块读取文件的函数 public static DataObject ReadNextFile 数据对象看起来像这样 public DataObject public string Category get set And ot
  • 静态类与类的实例

    我有一个静态类 用于访问我的公共属性 整个应用程序的全局属性 和我在应用程序运行期间使用的方法 例如 我在静态类中设置了一些属性 并且在应用程序运行时我可以从属性中获取值 但我可以使用单例模式创建非静态类并以相同的方式使用它 问题 对于我的
  • 你好,我最近正在开发我的新游戏,我遇到了*无限跳跃*的问题

    所以基本上当我按跳跃 空格键时我会跳跃但是如果我连续按空格键它 只是跳啊跳啊跳等等 我不想要我只想它跳一次 code if Input GetKeyDown space isGrounded velocity y Mathf Sqrt ju
  • 如何使用递归查找数字中的最小元素 [C]

    好的 所以我正在准备我的 C 考试 当谈到递归时我有点卡住了我是大学一年级的学生 这对我来说似乎有点困难 练习要求在给定的数字中使用递归函数我需要找到最小的元素 例如 52873 是 2 程序需要打印 2 include
  • Xamarin - SignalR 挂在连接上

    我正在尝试将我的 Xamarin 应用程序连接到托管在 Azure 上的 SignalR 后端 我遇到的问题是每次我在 HubConnection 上调用 StartAsync 时 它都会挂起客户端并且请求永远不会完成 我尝试通过应用程序进
  • 时间:2019-03-17 标签:c++fstream并发访问

    如果从不同的进程 线程同时访问文件会发生什么 据我所知 没有锁定文件的标准方法 只有操作系统特定的功能 就我而言 文件将被经常读取而很少写入 现在如果A打开一个文件进行读取 ifstream 并开始读取块 和B打开相同的文件进行写入 ofs
  • ALTER TABLE ... ADD CONSTRAINT 失败时将事务回滚到保存点

    有没有办法在事务中添加检查约束and如果失败回滚到以前的保存点 而不是回滚整个事务 就我而言 当 ALTER TABLE ADD CONSTRAINT 命令失败时 事务无法回滚到保存点 尝试这样做会引发 InvalidOperationEx
  • C# 中的 C/C++ 代码编译器

    在 C 中 我可以使用下面的代码编译 VB 和 C 代码 但无法编译 C C 代码 有什么办法可以做到这一点吗 C 编译器 public void Compile string ToCompile string Result null st
  • 为什么 f(i = -1, i = -1) 是未定义的行为?

    我正在读关于违反评估顺序 http en cppreference com w cpp language eval order 他们举了一个令我困惑的例子 1 如果标量对象上的副作用相对于同一标量对象上的另一个副作用是无序的 则行为未定义
  • 从 NumPy 数组到 Mat 的 C++ 转换 (OpenCV)

    我正在围绕 ArUco 增强现实库 基于 OpenCV 编写一个薄包装器 我试图构建的界面非常简单 Python 将图像传递给 C 代码 C 代码检测标记并将其位置和其他信息作为字典元组返回给 Python 但是 我不知道如何在 Pytho
  • 在哪里可以下载没有 Visual Studio 2010 的 C# 4.0 编译器?

    我知道 CTP VS 2010 映像 但我可以只下载 NET Framework 4 0 和 C 编译器吗 AFAIK VS 2010 CTP 仅作为 VM 映像提供 我不相信 Microsoft 发布了 VS 的安装程序 其中一个绝对不适
  • Linq.Select() 中的嵌套表达式方法调用

    I use Select i gt new T 每次手动点击数据库后将我的实体对象转换为 DTO 对象 以下是一些示例实体和 DTOS 用户实体 public partial class User public int Id get set
  • 有没有办法直接在函数参数中格式化字符串而不是使用临时字符串?

    我有一个接受字符串 字符数组 作为参数的函数 void enterString char my string 当使用这个函数时 我经常发现自己想要输入格式化的字符串 我使用 sprintf 来做到这一点 然而 我每次都必须创建一个临时字符串
  • “必须声明标量变量”错误[重复]

    这个问题在这里已经有答案了 必须声明标量变量 Id SqlConnection con new SqlConnection connectionstring con Open SqlCommand cmd new SqlCommand cm
  • SQL Server“未找到网络路径”在不同环境中随机且不频繁地发生

    类似 如果不是同一个问题 随机遇到网络路径未找到异常 https stackoverflow com questions 38696448 network path not found exception encountered rando

随机推荐

  • 哪里有一些好的 Xlib 编程指南?

    我现在对 Xlib 编程有点困惑 几周前我开始使用 dwm 一个轻量级窗口管理器 我想找一些 Xlib 编程书籍或在线资源来自定义 dwm 然而 在网上搜索后 我没有看到太多关于 Xlib 的新文章 亚马逊上最新的X窗口系统编程指南是199
  • 我的spark sql限制非常慢

    我使用spark从elasticsearch中读取 Like select col from index limit 10 问题是索引非常大 它包含 1000 亿行 而 Spark 会生成数千个任务来完成这项工作 我只需要 10 行 即使
  • 将 pyqtgraph 导出到视频

    我想将 pyqtgraph 导出到视频 有什么简单的方法可以做到这一点吗 该图与此示例没有太大区别 只是它包含大约 10000 帧 from pyqtgraph Qt import QtGui QtCore import numpy as
  • poi 中的 IRR 返回 NaN 但 excel 中的值正确

    当我使用 apache poi 计算 Irr 值时 我得到 Double NaN 但 excel 中的相同输入我得到负值 那么为什么它们返回不同的值呢 inputs here irr 1 0601017230994111E8 19150 6
  • React-native 链接找不到我的 MainApplication.java 文件

    每次我尝试react native link一个新的库 我收到同样的错误消息 这是用于react native video的 rnpm install info Linking react native video android depe
  • 为什么在 google chrome 浏览器中尝试时,javaScript 中的“navigator.userAgent”会返回字符串“Mozilla”?

    我正在开发 javaScript 代码 我想确定客户端浏览器的版本和品牌 这是我用来执行此操作的代码段 var browserName function BrowserCheckin if navigator userAgent index
  • 如何在 C# 中为大型 HTTP 请求设置 HttpWebRequest.Timeout

    我不知道如何处理 HttpWebRequest Timeout 之前 我曾经为 Socket 对象设置超时 这很简单 超时设置发送或接收数据块的最长时间 然而 HttpWebRequest Timeout 似乎设置了整个 HTTP 请求的超
  • Bash Shell 脚本 - 检查标志并获取其值

    我正在尝试制作一个 shell 脚本 其设计如下运行 script sh t application 首先 在我的脚本中 我想检查脚本是否已使用 t 标志运行 例如 如果它在没有像这样的标志的情况下运行 我希望它出错 script sh 其
  • 使用左值引用作为非类型模板参数[关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我读到以下类型允许作为非类型模板参数 整数类型 enum ptr 到对象 方法 对对象 方法的左值引用 std nullptr t 我不明白
  • 从 pandas 单元格中删除 html 格式

    我在 pandas 上有这个 DataFrame import pandas as pd df pd DataFrame CARGO 53944 Driver 57389 Driver 60851 Driver 64322 Driver 6
  • 在 LInux Mint 19.3 上安装 R4.0 时出现问题

    我尝试在 Linux Mint 19 3 上安装 R 4 0 但收到以下错误消息 The following packages have unmet dependencies r base core Depends libc6 gt 2 2
  • 如何在 Avfoundation 中正确更改采样率

    我已经完成了这个简单的程序 它的作用是同时记录和播放缓冲区 如果采样率为 44100 Hz 一切正常 但如果我将采样率更改为 16000 或 8000 它根本不会产生任何声音 或者可能是一些听不见的白噪声 为什么会发生这种情况 如何以不同的
  • Eclipse ADT 中的三星 Galaxy s4

    我想在 Samsung Galaxy S4 中测试我的应用程序 我已检查 未知来源 并启用开发人员菜单并检查 调试模式 但显示为离线状态 C Program Files x86 Android android sdk platform to
  • Webservice.wsdl 和凭据

    所以我有一个问题正在努力解决 也许一些 Flex 专家可以提供帮助 我有一个 WebService 实例 它尝试从 JBoss 应用程序服务器加载 WSDL 文件 如果我做这样的事情 webService new WebService we
  • 使用 @Valid 注释无法在本机检测到 JSR-303 错误

    为什么 Valid 注释本身不能捕获我的 JSR 303 注释 但可以使用以下方法捕获它们 WebConfig java Bean public ResourceBundleMessageSource messageSource Resou
  • 对于 IE 给出完整路径,仅需要文件名

    当从 IE 浏览器执行上传时 我的后端 org apache commons fileupload 获取完整的文件路径 对于其他非 IE 浏览器 它会获取文件名 并且出于安全考虑 这是可以的 如何获得filename只能从 IE 输入吗 是
  • 如何在playframework中从超类继承模型

    我试图了解继承是如何发挥作用的 但还没有成功 所以 我有这样的超类 Inheritance strategy InheritanceType TABLE PER CLASS abstract class SuperClass extends
  • 读取流中的实时完整输出

    注意 这篇文章与此有所不同post https stackoverflow com questions 1281140 run process with realtime output in php其接受的答案只是阅读每一行一次 我必须在服
  • Flutter:如何弹出对话框以及当前页面?

    下面是代码 从主页导航到登录页面 ElevatedButton onPressed gt Navigator of context rootNavigator true push MaterialPageRoute fullscreenDi
  • 如何在.Net中实现ConcurrentHashSet

    我正在尝试本着 ConcurrentDictionary 的精神实现 ConcurrentHashSet 采取的方法是使用内部支持 ConcurrentDictionary 并编写小型委托方法 这就是我所取得的进展 但是我坚持使用集合理论方