c# – InvalidOperationException:修改了集合 – 虽然锁定了集合

我有一个同步哈希表,我定期从中删除一些条目.多个线程运行此代码.所以我锁定了整个foreach,但我仍然有时会得到InvalidOperationException:Collection被修改了……在Hashtable.HashtableEnumerator.MoveNext() – 即在foreach循环中.
我究竟做错了什么?锁不够?
private static readonly Hashtable sessionsTimeoutData = Hashtable.Synchronized(new Hashtable(5000));

private static void ClearTimedoutSessions() { List keysToRemove = new List(); long now = DateTime.Now.Ticks; lock (sessionsTimeoutData) { TimeoutData timeoutData; foreach (DictionaryEntry entry in sessionsTimeoutData) { timeoutData = (TimeoutData)entry.Value; if (now - timeoutData.LastAccessTime > timeoutData.UserTimeoutTicks) keysToRemove.Add((ulong)entry.Key); } } foreach (ulong key in keysToRemove) sessionsTimeoutData.Remove(key); }

解决方法

您希望使用SyncRoot锁定,SyncRoot是同步Hashtable的方法将锁定的对象:
lock (sessionsTimeoutData.SyncRoot)
{
    // ...
}

http://msdn.microsoft.com/en-us/library/system.collections.hashtable.synchronized.aspx

Enumerating through a collection is
intrinsically not a thread-safe
procedure. Even when a collection is
synchronized,other threads can still
modify the collection,which causes
the enumerator to throw an exception.
To guarantee thread safety during
enumeration,you can either lock the
collection during the entire
enumeration or catch the exceptions
resulting from changes made by other
threads.

The following code example shows how
to lock the collection using the
SyncRoot during the entire
enumeration:

06001

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


1 在Visual Studio 中创建一个Asp.NET WebApi 项目,项目名:Com.App.SysApi(本例创建的是 .net 4.5 框架程序) 2 打开Nuget 包管理软件,查找 swagger 安装Swashbuckle 组件 3 开启项目的XML注释位置(选中项目Com.Ap
using ImpromptuInterface; using System; using System.Dynamic; namespace ConsoleApp2 { class Program { static void Main(string[] args) { dynamic expand
https://blog.csdn.net/michaelgong/article/details/43148597
C#11添加了文件作用域类型功能:一个新的file修饰符,可以应用于任何类型定义以限制其只能在当前文件中使用。 这样,我们可以在一个项目中拥有多个同名的类。 通过下面的项目显示,该项目包含两个名为Answer的类。 文件File1.cs中 namespace ConsoleApp11 { file
在.NET中Newtonsoft.Json(Json.NET)是我们常用来进行Json序列化与反序列化的库。 而在使用中常会遇到反序列化Json时,遇到不规则的Json数据解构而抛出异常。 Newtonsoft.Json 支持序列化和反序列化过程中的错误处理。 允许您捕获错误并选择是处理它
设置允许跨域访问的网址--> 设置预检有效时间--> -->
先来看一点实例,两个类之间的映射。 首先定义两个类Source与DTOSource: Source与DTOSource字段完全相同,来看看它俩如何通过AutoMapper转换,代码很简单。 第一步建立Source到DTOSource之间的映射,初始化一个Source实例后,来看下执行结果: 执行完成
C#中提供了IObservable<T>接口和IObserver<T>接口来实现观察者模式,IObservable<T>相当于Subject(主题)接口,下面我们就以代吗来说明下如何利用.net框架提供的观察者模式接口。 WeatherData类包含气温,湿度,气
class Program { private static readonly DiagnosticSource testDiagnosticListener = new DiagnosticListener("TestDiagnosticListener"); public s
.Net Core在调用其他服务时,调用通常使用HttpClient,而HttpClient默认使用HTTP/1.1 。 配置 HttpClient 以使用 HTTP/2 h2 连接 自 .NET Core 3.0 发布以来, .NET 开发人员可以使用 HttpClient 启用 HTTP/2 。
转自:https://www.cnblogs.com/neverc/p/5241466.html AOP介绍 面向切面编程(Aspect Oriented Programming,英文缩写为AOP),通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。 AOP是OOP的延续,是软件开发中
<PropertyGroup> <RunWorkingDirectory>../../</RunWorkingDirectory> </PropertyGroup>
https://www.cnblogs.com/ideacore/p/7803606.html 1.安装T4 Toolbox 2.新建T4 Toolbox模板 3.编辑T4 Toolbox模板 Bbing_Template_Mongo_Service.tt 4.添加T4模板 Bbing_T
using System; using System.Collections.Generic; using System.Text; using Dapper; using System.Data; using System.Data.SqlClient; using System.Linq; us
using cpf360.Common; using cpf360.ModelInfo; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Thread
public ActionResult Login(string data) { var _params = JsonConvert.DeserializeAnonymousType(data, new { userName = "", password = "&quo
什么是Elastic AMP Elastic APM 是一个应用程序性能监控系统。它可以请求的响应时间、数据库查询、对缓存的调用、外部 HTTP 请求等的详细性能信息,可以实时监控软件服务和应用程序。这可以帮助我们快速查明和修复性能问题。 Elastic APM 还会自动收集未处理的错误和异常。因此
#user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; ev
背景 前些天遇到一个需求,在没有第三方源码的情况下,刷新一个第三方UI,并且拦截到其ajax请求的返回结果。当结果为AVALIABLE的时候,停止刷新并语音提示,否则继续刷新。 分析这个需求,发现需要控制一个刷新循环的暂停与开始,因此网上搜到了通过ManualResetEvent实现线程的暂停与恢复
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using cpf360.Common; using cpf360.DTO; name