2010年3月26日星期五

使用Linq to sql 一个可能导致内存溢出的写法

最近由于系统的升级,经常会做一些对大量数据的批量更新的需求,因此常写一些处理工具来运行这些更新,前几天就发现我写的小工具会在运行一段时间后出现 OutOfMemory的错误,后来发现此问题源于Linq的一点使用不当导致的,看下面一段代码:

  long lastID = 0;

            using (MainDataContext db = new MainDataContext("...."))

            {

                while (true)

                {

                    var task = from t in db.Table where t.ID > lastID select t;

       if(task.Count()==0)

        break; 

                    foreach (var atask in task)

                    {

                        //TODO 做相应处理

                    }

                }

            }

 

这样写的原因是, 想着在循环的外部创建一个MainDataContext,也就相当于保持了一个SQLServer链接,这样性能上会好一些,但DataContext这种东西是会自动保持上下文的,当我窒息了一次 select之后,虽然该变量时在while内部定义的,但在执行完相应的操作之后,这些被取出的数据并没有从数据库中移除,而是不断积累起来,这样就导致了在程序运行的过程中,内存不断的增加。

 当我修改了以上代码,把DataContext的创建放在循环内部之后,内存溢出的问题解决,而且性能上也比上面的写法好了一些。



__________ Information from ESET Smart Security, version of virus signature database 4975 (20100325) __________

The message was checked by ESET Smart Security.

http://www.eset.com

一些生活上的小哲理,细细琢磨蛮有用的

管理者的六修养。一:沉稳 (1)不要随便显露你的情绪。 (2)不要逢人就诉说你的困难和遭遇。 (3)在征询别人的意见之前,自己先思考,但不要先讲。 (4)不要一有机会就唠叨你的不满。 (5)重要的决定尽量有别人商量,最好隔一天再发布。 (6)讲话不要有任何的慌张,走路也是。

如果你帮助过别人,过后不要经常提及。如果对方知道感恩,他会记住的。如果他不知道感恩,你说也没用,甚至适得其反。做完好事,全当没做。挺好的。