zoukankan      html  css  js  c++  java
  • DataTable多线程操作报错情况

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

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

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

    1 object oblock = new object();
    2 
    3 lock(oblock)
    4 {
    5     //我的dataTable对rows操作的代码
    6 }

    信心满满的开始继续用压力测试工具来测试。结果还是报错;因为是并发操作你几乎不能用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锁。

    
    
    
  • 相关阅读:
    Kafka 生产者 自定义分区策略
    同步互斥
    poj 1562 Oil Deposits(dfs)
    poj 2386 Lake Counting(dfs)
    poj 1915 KnightMoves(bfs)
    poj 1664 放苹果(dfs)
    poj 1543 Perfect Cubes (暴搜)
    poj 1166 The Clocks (暴搜)
    poj 3126 Prime Path(bfs)
    处理机调度
  • 原文地址:https://www.cnblogs.com/rui1236/p/4567420.html
Copyright © 2011-2022 走看看