C# .NET 4.0下多线程使用List偶发线程安全问题

前提

使用主线程List集合去接收子线程下的元素数据会偶发索引超出了数组的界限 Index was outside the bounds of the array 问题!

例如:

        public IList GetThreadData(){IList dt = new List();Task[] tasks = new Task[100];Task task;Debug.WriteLine("模仿" + tasks.Length + "次数据接口请求开始:" + DateTime.Now);for (int i = 0; i < tasks.Length; i++){tasks[i] = new Task(o =>{Debug.WriteLine($"子线程ID:{Thread.CurrentThread.ManagedThreadId}");dt.Add(GetData(Convert.ToInt32(o)));}, i);tasks[i].Start();}Task.WaitAll(tasks);Debug.WriteLine($"主线程ID:{Thread.CurrentThread.ManagedThreadId}");Debug.WriteLine("模仿" + tasks.Length + "次数据接口请求结束:" + DateTime.Now);return dt;}

解决

主体实现

        public IList GetThreadData(){//若直接使用list集合会导致线程安全问题偶发,所以需要使用线程安全集合//IList dt = new List();            //这是因为List是非线程安全的类,我们需要使用System.Collections.Concurrent命名空间下的类型来用于并行循环体内ConcurrentQueue queueDto = new ConcurrentQueue();Task[] tasks = new Task[100];Debug.WriteLine("模仿" + tasks.Length + "次数据接口请求开始:" + DateTime.Now);//并行循环Parallel.For(0, tasks.Length, (i) =>{tasks[i] = new Task(o =>{Debug.WriteLine($"子线程ID:{Thread.CurrentThread.ManagedThreadId}");queueDto.Enqueue(GetData(Convert.ToInt32(o)));}, i);tasks[i].Start();});Task.WaitAll(tasks);Debug.WriteLine($"主线程ID:{Thread.CurrentThread.ManagedThreadId}");Debug.WriteLine("模仿" + tasks.Length + "次数据接口请求结束:" + DateTime.Now);return queueDto.ToList();}

模拟接口调用

        public Dto GetData(int id){var dto = new Dto();dto.ID = id + 1;dto.Name = new List() { "张三", "李四", "王五", "赵六", "刘七", "马八" }.OrderBy(u => Guid.NewGuid()).First() + (id + 1).ToString();Thread.Sleep(100);dto.Age = new Random().Next(16, 40);dto.Sex = new List() { "男", "女" }.OrderBy(u => Guid.NewGuid()).First();dto.Money = new Random().Next(0, 10000);dto.Email = new List() { "528414865@qq.com", "123456@qq.com", "mwl_mark@qq.com", "77777@qq.com", "qwerto@qq.com" }.OrderBy(u => Guid.NewGuid()).First();dto.QQ = new List() { "528414865", "123456", "7777777", "8715373" }.OrderBy(u => Guid.NewGuid()).First();dto.WeiXin = new List() { "ma528414865", "zhang1111111", "wang7777777", "li123456" }.OrderBy(u => Guid.NewGuid()).First();dto.Address = new List() { "上海-浦东", "陕西-西安", "湖北-武汉" }.OrderBy(u => Guid.NewGuid()).First();dto.Phone = new List() { "13189016728", "17612475521", "13811381627", "16601826471" }.OrderBy(u => Guid.NewGuid()).First();dto.Dept = new List() { "信息技术部", "运维部", "运营部", "营销部" }.OrderBy(u => Guid.NewGuid()).First();dto.Hobby = new List() { "Game", "tomcat", "baidu", "google" }.OrderBy(u => Guid.NewGuid()).First();dto.Accout = new List() { "528414865", "7777777", "zhangsan", "lisi", "wangwu" }.OrderBy(u => Guid.NewGuid()).First();dto.Password = "******";return dto;}

Dto模型类

    public class Dto{public int ID { get; set; }public string Name { get; set; }public int Age { get; set; }public string Sex { get; set; }public decimal Money { get; set; }public string Email { get; set; }public string QQ { get; set; }public string WeiXin { get; set; }public string Address { get; set; }public string Phone { get; set; }public string Dept { get; set; }public string Hobby { get; set; }public string Accout { get; set; }public string Password { get; set; }}

使用

GetThreadData();


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部