背景

由于项目中需要导入大量数据到memcache中
需要用WCF调取11万条数据,由于那边多级联查和排序,所以比较慢(1分钟左右)
同时这边需要对数据进行处理,合并成2万条数据,然后存储,需要一定时间(也是1分钟左右)
总之,完成这个数据导入一共需要1分30秒左右

这时候,需要一个进度条来实时监测完成的数据量
(之前用的是一个动态图,不能知道程序目前的完成量,甚至不知道它是不是卡住了,只能等着)


功能

1.开辟线程,用于加载数据,处理数据
2.前台实时读取后台数据,并显示


代码

view-html

@* 数据准备进度条 *@
    <div id="container">
        <div class="content">
            <h1>数据准备</h1>
        </div>
        <!-- Progress bar -->
        <div id="progress_bar" class="ui-progress-bar ui-container">
            <div class="ui-progress" style="width: 3%;">
                <span class="ui-label" style="display: none;">完成量<b class="value">3%</b></span>
            </div>
        </div>
        <!-- /Progress bar -->
        <div class="content" id="main_content" style="display: none;">
            <p>数据准备完成!</p>
        </div>
    </div>

view-js

$(function () {
        $('#initialization').click(function () {
            $.messager.confirm('提示', '是否要进行数据初始化?', function (r) {
                if (!r) {
                    return;
                }
                else {
                    $('#container').show();
                    var t1 = window.setInterval(process_bar, 1500);
                }
            });
        });
    });

    function process_bar() {
        $.ajax({
            type: "POST",
            async: true,
            url: "/Paper/LoadData",
            success: function (result) {
                $('#progress_bar .ui-progress').animateProgress(result);
                if (result =="100") {
                    $('#main_content').slideDown();
                    $('#fork_me').fadeIn();
                    setTimeout(function () { $('#container').hide();; }, 1500);
                    window.clearInterval(t1);
                }
            }
        })
    }

controller

static bool flag = true;

        public int LoadData()
        {
            int result = Ipaperbll.LoadDataAmount();
            if (flag)
            {
                Thread thread = new Thread(new ThreadStart(ThreadLoadData));
                thread.Start();
                flag = false;
            }
            return result;
        }


        private void ThreadLoadData()
        {
            Ipaperbll.initializeData();
        }

后台

static int load_data_amount;//当前数据准备量
        public bool initializeData()
        {
            bool flag = false;    //定义返回值

            //获得数据
            //code....code ....code....
            load_data_amount = 5;//完成工作量

            int page = 0;
            int amount = 50000;//一次获取数据量不能超过10万
            while (page * amount == list.Count)
            {
                //code....code ....code....
                load_data_amount = load_data_amount + 5;
            }
            load_data_amount = 50;//读取数据默认的工作量

            double totalamount = list.Count();
            foreach (var item in list)
            {
                //code....code ....code....
                load_data_amount = Convert.ToInt32((1 - (totalamount--) / double.Parse(list.Count().ToString())) * 50) + 50;//根据数据改变的完成工作量
            }
            load_data_amount = 100;//完成工作量

            flag = true;
            return flag;
        }

        //返回当前准备数据量
        public int LoadDataAmount() {
            return load_data_amount;
        }

问题 & 解决

1.进度条生成
解决:使用网上的demo,css+js可以动态生成,改变数据即可

2.线程问题
解决:开始是监测使用线程,后来改成处理数据使用线程

3.实时监测问题
解决:处理数据使用线程自动运行,前台使用ajax不断查询后台的一个变量load_data_amount

4.ajax报错问题
注意是返回值的类型,以及是result还是result.d,不同情况下是不一样的

5.数据类型问题
解决:读取数据完成的百分比,是用 完成量/所有量 得到的,这里的数一直算不对,是因为int类型承受不住11万的运算以及之后的小数,用double和float可以


小结

本来想着开个线程,加个变量,返回前台,加一个进度条,读取变量就OK了

但是中间的这个MVC,这个Spring,这个接口,之前的方法各种不好使,以及在它们下面的运算,ajax……一个一个分开解决,最后还是解决了

分而治之,逐个解决,测试就好

另外,框架和合作在带来便利的同时,中间的限制和bug也会让你的效率下降