本错误的环境是.Net4.0,数据库访问使用LinQ。本例在数据库访问的类里面将DBAccessDataContext (数据库上下文)做为类变量,后面的数据库操作函数都使用这个类变量,在多线程的环境下面就爆出了[System.InvalidOperationException] = {"阅读器关闭时尝试调用 MetaData 无效。"} 的错误。
具体的代码见下方
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 public class test1 { 2 DBAccessDataContext db = new DBAccessDataContext() 3 4 public string GetName(int id) 5 { 6 return (from user in db.DBUser select user.name).FirstOrDefault(); 7 } 8 }
解释如下:
DBAccessDataContext依赖的Connection不能再用来执行其他Command命令。所以你的代码段会报“已有打开的与此命令相关联的 DataReader,必须首先将它关闭。” 错误提示。
解决方法如下:
方法1、使用多线程控制的方法。用信号量来控制同一个时间只能有一个线程来访问这个函数。
1 public class test1 { 2 //将类变量降级为局部变量 3 //DBAccessDataContext db = new DBAccessDataContext() 4 public string GetName(int id) 5 { 6 using (DBAccessDataContext db = new DBAccessDataContext())//降级后的变量 7 { 8 return (from user in db.DBUser select user.name).FirstOrDefault(); 9 } 10 } 11 }
方法2、使用将类变量降级为局部变量,这个就不存在多线程中的资源冲突(具体代码见下方)。
1 public class test1 { 2 //使用lock进行访问控制,保证同一时间只能有一个线程访问。 3 DBAccessDataContext db = new DBAccessDataContext() 4 public string GetName(int id) 5 { 6 lock(db){ 7 return (from user in db.DBUser select user.name).FirstOrDefault();} 8 } 9 }
2013-01-0112:16:44