每次从数据源中读取数据后,添加到batchItems列表中,当batchItems满1000条时便进行一次提交。这段代码功能运行正常,可惜时间卡在了数据库提交上。数据的获取和处理很快,但是提交一次就要花较长时间。于是想想,数据提交和数据处理不会有资源上的冲突,那么就把数据提交放在另外一个线程上进行处理吧!于是,使用ThreadPool来改写代码:
- static void Process() {
- List<Item> batchItems = new List<Item>(); foreach (var item in ...)
- { batchItems.Add(item);
- if (batchItems.Count > 1000) {
- ThreadPool.QueueUserWorkItem((o) => {
- DataContext db = new DataContext(); db.Items.InsertAllOnSubmit(batchItems);
- db.SubmitChanges(); });
- batchItems = new List<Item>(); }
- } }
现在,我们将数据提交操作交给ThreadPoll执行,当线程池中有额外线程时,就会发起数据提交操作。而数据提交操作不会阻塞数据处理,因此按照那位兄弟的意图,数据会不断进行处理,最后只要等待所有数据库提交完成就可以了。思路很好,可惜运行时发现,原本(不利用多线程时)运行正常的代码,如今会“莫名其妙”地抛出异常。更为奇怪的是,数据库中的数据出现了丢失的情况:处理了并“提交”了一百万条数据,但是数据库里却少了一部分。于是对着代码左看右看,百思不得其解。
您看出问题原因来了吗?
分析原因
要发现问题所在,我们必须了解匿名方法在.NET环境中的实现方式。










