最近在写一个http接口时用了DataTable这个强大的利器,接口用浏览器跑起来没任何问题。当时也没考虑并发问题,后来用一个压力测试工具做大并发测试,1000+/s次速度测试。发现程序报错了。程序报错了第一反应还是去检查代码,是不是代码出现问题。发现逻辑都是对的,然后用浏览器打开接口,发现一切OK;然后心想肯定是并发时多个线程操作导致的。

我们都知道在多线程的时候不同的线程访问同一个资源的时候,用lock方法来达到线程同步,也就是同一个时刻同一个资源只能被一个线程操作。

我开始在操作DataTable的函数前面加上:

 object oblock = new object();

 lock(oblock)
{
//我的dataTable对rows操作的代码
}

信心满满的开始继续用压力测试工具来测试。结果还是报错;因为是并发操作你几乎不能用vs进行断点调试;所以也不好找到具体的错误在什么地方。然后就try catch 打印错误日志找到具体异常原因和所在代码行。提示的错误有时候都不尽相同;有“内部索引损坏”、"在位置0处没有任何行" 等等。加了lock还报错就感觉挺纳闷的;当这段代码被锁定以后应该是不会被其他线程操作,也就不会导致行的索引出现问题。

后来找些资料发现,因为我们平时对DataTable的操作基本是Rows操作,所以我上面lock的代码里面只锁定了DataTable的Rows;但是因为我没有操作Columns,所以其他线程还可以访问DataTable的Columns集合。但是Rows是共享一个Columns的;罪魁祸首应该是没有锁住Columns导致的。

解决方法:

通过百度知道.Net里DataTable.Rows集合上提供.SyncRoot同步对象,正是为了在多线程环境下锁住DataTable中的Rows集合同时也锁住了Columns集合。

所以我们只需要在要操作DataTable代码的前面加上:


1 //你要操作的 DataTable
2 DataTable dtb = new DataTable();
3 lock(dtb.Rows.SyncRoot)
4 {
5 //你的DataTable处理代码
6 }

注:并不是所有DataTable在多线程操作是都会报错;视具体情况而定。但是为了线程安全在多线程下操作是最好加上Rows.SyncRoot锁。

												

DataTable多线程操作报错情况的更多相关文章

  1. dotnetcore ef 调用多个数据库时用户命令执行操作报错

    dotnetcore ef 调用多个数据库时用户命令执行操作报错 1.多个DbContext 时报错: 报错: More than one DbContext was found. Specify w ...

  2. Ansible 脚本运行一次后,再次运行时出现报错情况,原因:ansible script 的格式不对,应改成Unix编码

    Ansible 脚本运行一次后,再次运行时出现报错情况,原因:ansible  script 的格式不对,应改成Unix编码 find . -name "*" | xargs do ...

  3. ORACLE数据导入导出后新数据库中某些表添加操作报错[ORA-12899]

    由于项目需要,我在搭建了新的开发环境后,需要将之前环境中的ORACLE数据库导出,再导入到新的开发环境下.当导出导入完成后,使用数据库进行添加操作时 发现针对很多表的添加操作报错,具体报错原因描述为: ...

  4. 【疑难杂症】gdb调试多线程程序报错:interrupted system call

    一. cmake生成可调试版本的程序,该内容参考自https://www.linuxidc.com/Linux/2014-03/98622.htm 具体内容如下: 1, 使用CMAKE编译确实很方便. ...

  5. 解决升级Spark2.0之后,DataFrame map操作报错

    当我们在使用spark1.6的时候,当我们创建SQLContext读取一个文件之后,返回DataFrame类型的变量可以直接.map操作,不会报错.但是升级之后会包一个错误,如下: 报错:No imp ...

  6. postgresql shell发起select操作报错ERROR: relation "tablename" does not exist

    最近安装了一套clourdera manager,其中hive元数据保存在postgresql中,因为今天想看一下hive的元数据信息,就登录了psql,连接到hive元数据库,发起select操作, ...

  7. Elasticsearch聚合操作报错解决办法

    1. 当根据一个类型为text的字段idc进行聚合操作时,查询语句如下: { "aggs": { "top_10_states": { "terms& ...

  8. 解决Git操作报错

    情况一: 当我拉取的代码是最新的时候,git pull是可以正常的拉取的,但是却不可以提交,报错如下图: 情况二: 如果我目前不是最新的版本,需要git pull,此时拉取就会失败,报错如下图: 出现 ...

  9. Eclipse/MyEclipse向HDFS中如创建文件夹等操作报错permission denied解决办法

    不多说,直接上干货! 问题现象 当执行创建文件的的时候, 即: String Path = "hdfs://host2:9000"; FileSystem fileSystem = ...

随机推荐

  1. java基础---->hashMap的简单分析(一)

    HashMap是一种十分常用的数据结构对象,可以保存键值对.它在项目中用的比较多,今天我们就来学习一下关于它的知识. HashMap的简单使用 一.hashMap的put和get方法 Map<S ...

  2. hdu3586 Information Disturbing 树形DP+二分

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3586 题目大意:给定n个敌方据点,编号1为司令部,其他点各有一条边相连构成一棵树,每条边都有一个权值c ...

  3. [刷题]算法竞赛入门经典(第2版) 4-1/UVa1589 - Xiangqi

    书上具体所有题目:http://pan.baidu.com/s/1hssH0KO 代码:(Accepted,0 ms) //UVa1589 #include<iostream> #incl ...

  4. Centos6.5安装memcached

    1.检查libevent 首先检查系统中是否安装了libevent(Memcache用到了libevent这个库用于Socket的处理). # rpm -q libevent libevent-1.4 ...

  5. Oracle 12C 新特性之move (非分区表)table online

    以前版本中move table不能够online, move 会引rowid改变使对应的索引失效. 12c 中 alter table move online不会对新事务阻塞同时会自动的维护索引的有效 ...

  6. 在ASP.NET Core 中使用Cookie中间件

    在ASP.NET Core 中使用Cookie中间件 ASP.NET Core 提供了Cookie中间件来序列化用户主题到一个加密的Cookie中并且在后来的请求中校验这个Cookie,再现用户并且分 ...

  7. 关于Dubbo一个接口多个实现的解决方案

    如题,其实这个问题在官方文档中已经说明了.我直接贴图就好了 更多学习请参考:minglisoft.cn/technology

  8. 《Android进阶》之第六篇 Fragment 的使用2

    最近通过学习,对fragment的使用有了新的认识. 一开始接触android的时候,很是受不了这个fragment,总感觉它把一个简单的事情搞复杂啦,所以每次新建工程的时候总是固执的选择empty ...

  9. zookeeper的安装与配置

    本文将通过三个zookeeper的节点去配置 1.首先去官网下载zookeeper的包 zookeeper-3.4.10.tar.gz 2.用FTP文上传到/usr/local下 3.解压文件tar ...

  10. cookie创建,删除

    Cookie 历来指就着牛奶一起吃的点心.然而,在因特网内,“Cookie”这个字有了完全不同的意思.那么“Cookie”到底是什么呢?“Cookie”是小量信息,由网络服务器发送出来以存储在网络浏览 ...