架构师_程序员_码农网

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

搜索
查看: 21884|回复: 0

[资料] C#在多线程环境中,进行安全遍历操作

[复制链接]
发表于 2016-10-18 13:55:48 | 显示全部楼层 |阅读模式

本文以List作为操作对象
MSDN官方给出的List的线程安全的说法:
此类型的公共静态成员是线程安全的。但不能保证任何实例成员是线程安全的。
只要不修改该集合,List 就可以同时支持多个阅读器。通过集合枚举在本质上不是一个线程安全的过程。在枚举与一个或多个写访问竞争的罕见情况下,确保线程安全的唯一方法是在整个枚举期间锁定集合。若要允许多个线程访问集合以进行读写操作,则必须实现自己的同步。
如果不进行同步操作?
假如一个线程进行删除操作,一个线程进行遍历操作,那么在遍历过程中,集合被修改,会导致出现InvalidOperationException的异常,提示:集合已修改;可能无法执行枚举操作。
如何同步,保证遍历的安全
这里使用了临界区,互斥锁来保证线程遍历过程的安全,示例代码如下:
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Threading;

  4. namespace ConsoleApp
  5. {
  6.     class Program
  7.     {
  8.         public static List<string> simpleList = new List<string>();
  9.         
  10.         public static void Main(string[] args)
  11.         {
  12.             // 临界区对象
  13.             object lockObj = new object();

  14.             // 向List中添加测试数据
  15.             string[] data = { "1", "2", "3", "4", "5", "6", "7", "8" };
  16.             simpleList.AddRange(data);
  17.             // 此线程用于遍历数组
  18.             new Thread(new ThreadStart(() =>
  19.             {
  20.                 // 用于同步,进入临界区,只有遍历完,释放临界区对象的互斥锁,才能进行写操作
  21.                 lock (lockObj)
  22.                 {
  23.                     foreach (var item in simpleList)
  24.                     {
  25.                         Console.WriteLine(item);
  26.                         Thread.Sleep(500);
  27.                     }
  28.                 }
  29.             })).Start();
  30.             // 此线程执行删除操作
  31.             new Thread(new ThreadStart(() =>
  32.             {
  33.                 lock (lockObj)
  34.                 {
  35.                     simpleList.RemoveAt(0);
  36.                     Console.WriteLine("rm 1");
  37.                     Thread.Sleep(500);
  38.                     simpleList.RemoveAt(0);
  39.                     Console.WriteLine("rm 2");
  40.                 }
  41.             })).Start();

  42.             Console.ReadLine();
  43.         }
  44.     }
  45. }
复制代码






上一篇:微信公众号在联通网络下jssdk签名错误的解决办法
下一篇:asp.net MVC全局异常处理与异常日志
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

免责声明:
码农网所发布的一切软件、编程资料或者文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。

Mail To:help@itsvse.com

QQ|小黑屋|架构师 ( 鲁ICP备14021824号-2 )|网站地图

GMT+8, 2026-10-29 23:15

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表