使用.net Core 3.1 多线程读取数据库
第一步:先创建一个DBhepler类,作为连接数据库中心,这个不过多说明,单纯作为数据库的连接...........
1 public static string Constr = "数据库连接字符串"; 2 public static DataTable Select(string sql, SqlParameter[] sp) 3 { 4 using (SqlConnection conn = new SqlConnection(Constr)) 5 { 6 conn.Open(); 7 DataTable dt = new DataTable(); 8 SqlCommand cmd = new SqlCommand(sql, conn); 9 if (sp != null) 10 { 11 cmd.CommandType = CommandType.StoredProcedure; 12 cmd.Parameters.AddRange(sp); 13 14 } 15 16 SqlDataAdapter sdr = new SqlDataAdapter(cmd); 17 sdr.Fill(dt); 18 conn.Close(); 19 return dt; 20 } 21 22 }
第二步:将读取的DataTable,数据信息转换为List
1 public static IList<T> TableToListModel<T>(DataTable dt) 2 where T : new() 3 { 4 5 6 IList<T> ts = new List<T>();// 定义集合 7 8 foreach (DataRow dr in dt.Rows) 9 { 10 11 lock (obj_Lock)//就给锁住,注意这里是要加锁的,虽然我执行的时候没加锁,也成功了,但还是要加上............具体原因,你猜.... 12 { 16 T t = new T(); 17 PropertyInfo[] propertys = t.GetType().GetProperties();// 获得此模型的公共属性 18 foreach (PropertyInfo pi in propertys) 19 { 20 //获取属性名称 21 String name = pi.Name; 22 if (dr.Table.Columns.Contains(name)) 23 { 24 //非泛型 25 if (!pi.PropertyType.IsGenericType) 26 { 27 pi.SetValue(t, string.IsNullOrEmpty(dr[name].ToString()) ? null : Convert.ChangeType(dr[name], pi.PropertyType), null); 28 } 29 //泛型Nullable<> 30 else 31 { 32 Type genericTypeDefinition = pi.PropertyType.GetGenericTypeDefinition(); 33 //model属性是可为null类型,进行赋null值 34 if (genericTypeDefinition == typeof(Nullable<>)) 35 { 36 //返回指定可以为 null 的类型的基础类型参数 37 pi.SetValue(t, string.IsNullOrEmpty(dr[name].ToString()) ? null : Convert.ChangeType(dr[name], Nullable.GetUnderlyingType(pi.PropertyType)), null); 38 } 39 } 40 } 41 } 42 ts.Add(t); 43 44 } 45 } 46 return ts; 47 }
第三步 :为了能够将代码打印出来,,更好的展示效果,我试图用以下方法展示
public static IList<GHXX> zhuanhaun(string sql) { DataTable dt = DBHelper.Select(sql, null); IList<GHXX> gHXXes = TableToListModel<GHXX>(dt); return gHXXes; } public static void showlist(string sql, int index) { IList<GHXX> gHXXes = zhuanhaun(sql); for (int i = 0; i < gHXXes.Count; i++) { Console.WriteLine("序号:{0},我来自第{1}个线程,编号:{2},类别:{3},门诊编号:{4},姓名:{5}", i, index, gHXXes[i].MENZH, gHXXes[i].LEIB , gHXXes[i].MENZKS, gHXXes[i].XINGM); } }
第四步:接下来就是启动线程执行了
1 Stopwatch sw = new Stopwatch(); 2 sw.Start(); 3 string sql1 = " 查询的SQL1"; 4 string sql2 = ""; 5 string sql3 = ""; 6 string sql4 = ""; 7 8 9 TaskFactory taskFactory = new TaskFactory(); 10 List<Task> taskList = new List<Task>();
//我开启了四个线程执行 11 taskList.Add(taskFactory.StartNew(() => 12 { 13 showlist(sql1, 1); 14 })); 15 16 taskList.Add(taskFactory.StartNew(() => 17 { 18 showlist(sql2, 2); 19 })); 20 taskList.Add(taskFactory.StartNew(() => 21 { 22 showlist(sql3, 3); 23 })); 24 taskList.Add(taskFactory.StartNew(() => 25 { 26 showlist(sql4, 4); 27 })); 28 29 30 sw.Stop(); 31 TimeSpan ts2 = sw.Elapsed; 33 Task.WaitAny(taskList.ToArray());//也可以限时等待 34 Console.WriteLine("其中一个线程执行完毕...."); 35 36 37 Task.WaitAll(taskList.ToArray()); 38 Console.WriteLine("线程全部执行完成,运行时间:" + ts2.TotalMilliseconds);
所以就好了..............
然后执行
开启四个线程查询8000条数据,耗时如图所示
没用启用线程执行,耗时: