C#多线程并发处理的问题

@老徐  May 27, 2017

公司某业务,需要按条来处理大批量数据,大概几万条到几十万条都有可能。这个是由另外一个同事写的,写完之后测试,速度、效率都非常低。我问了下,原来是直接拿这些数据进行循环处理,之后又把有问题的数据循环入库。
这就有两个瓶颈,一个是单线程处理数据,另一个就是又一次循环入库。
我给出的建议是,处理数据部分多线程,处理完数据之后直接把有问题的数据入库。可是同事用不明白多线程,那好吧,我给写个Demo吧。
这里需要用到队列(Queue)和Task或Thread。我这里使用的是ConcurrentQueue,ConcurrentQueue队列是一个高效的线程安全的队列,是.Net Framework 4.0,System.Collections.Concurrent命名空间下的一个数据结构。
首先,实例化一个队列,名为queue:
private ConcurrentQueue<Models.Demo> queue;
之后,给这个队列填充上测试用的数据:

//生成测试用数据列表
for (int i = 1; i <= 50000; i++)
{
    Models.Demo dat = new Models.Demo() { id = i, value = Libs.Rand.RndCode(8) };
    queue.Enqueue(dat);
    Thread.Sleep(1);    //这里是随机数生成时需要
}

下面是处理启用多线程来处理数据了

int threadcount=10; //开启10个线程

for(int i=0;i<threadcount;i++)
{
    string filename = string.Format("task{0}.txt", i);
    filename = System.Web.HttpContext.Current.Request.MapPath(string.Format("~/file/{0}", filename));
    Task.Factory.StartNew(() =>
    {        
        Models.Demo demo = new Models.Demo();
        StringBuilder sb = new StringBuilder();
        int j = 0;
    
        while (queue.TryDequeue(out demo))
        {
            //处理数据
            if (demo != null)
                sb.AppendLine(string.Format("{0}.{1}", demo.id, demo.value));

            if (j % 100 == 0 ||  (queue.Count.Equals(0) && j<100))
            {   //每100条写一次文件,并暂停100毫秒
                Libs.FileObj.WriteFile(filename, sb.ToString());
                sb = new StringBuilder();
                Thread.Sleep(100); 
            }
            j++;
        }
    });
}

这就搞定了。以上。


添加新评论

  1. 121

    图一代码Libs是啥啊,大神

    Reply
    1. @121

      那个Libs是自己收集整理的一个类库,Libs.FileObj.WriteFile()是写文本文件

      Reply