用多线程处理后台业务,并提高处理速度

本文主要探讨一下用后台线程和线程池来处理后台业务,以便提高系统响应速度。

假设现在后台需要处理20000条数据,在数据处理完成后,将处理结果输出。

首先考虑的是用多个后台线程来处理这20000条数据,每个线程处理其中的一部分,等到所有线程处理完成后,再将数据输出。因此这里需要一个事件的触发,当所有线程完成工作后立即触发这个事件,在这个事件中将处理结果输出。

private delegate void tempChange(object sender, EventArgs e);//定义委托
private event tempChange OntempChange;
private IList<string> mstrlist = null;
private int conplate = 0; private int Conplate { set { conplate = value; if (2 == value)//当conplate =2的时候,表示所有线程处理完成,这里只开了2个线程 OntempChange(this, new EventArgs()); } get{return conplate;} } //这是窗口的构造函数 public Threads() { InitializeComponent(); mstrlist = new List<string>(); mdd = new Dictionary<string, string>(); OntempChange += new tempChange(ven_OntempChange); OntempChange1 += new tempChange(ven_OntempChange1); } //点击按钮后,开始执行任务 private void Button_Click(object sender, RoutedEventArgs e) { txt.Text = ""; conplate = 0; object synObj = new object(); Thread t1 = new Thread(o => { for (int i = 0; i < 10000; i++) {/*lock(obj){…}后面两个大括号直接的代码称为临界区。当一个线程执行位于代码的临界区时,另一个线程会阻止在临界区外,不会进入该临界区,一直到该lock(obj)锁定的象obj被释放。*/ lock (synObj) { mstrlist.Add(i.ToString());} } Dispatcher.BeginInvoke(new Action(() => { Conplate++; })); }); t1.IsBackground = true; Thread t2 = new Thread(o=>{ for (int i=10000;i<20000;i++){ lock (synObj) { mstrlist.Add(i.ToString()); } } Dispatcher.BeginInvoke(new Action(() => { Conplate++; })); }); t2.IsBackground = true; t1.Start(); t2.Start(); } //这个是触发事件的回调函数 private void ven_OntempChange(object sender, EventArgs e) { int i =1; string text = ""; object synObj = new object(); new Thread(o => { for (int j = 0; j < 1000; j++) { lock (synObj) { text += mstrlist[j] + ","; } } Dispatcher.BeginInvoke(new Action(() => { if (i == 4) txt.Text = text; else i++; })); }){IsBackground=true}.Start(); new Thread(o => { for (int j = 1000; j < 5000; j++) { lock (synObj) { text += mstrlist[j] + ","; } } Dispatcher.BeginInvoke(new Action(() => { if (i == 4) txt.Text = text; else i++; })); }) { IsBackground = true }.Start(); new Thread(o => { for (int j = 5000; j < 12000; j++) { lock (synObj) { text += mstrlist[j] + ","; } } Dispatcher.BeginInvoke(new Action(() => { if (i == 4) txt.Text = text; else i++; })); }) { IsBackground = true }.Start(); new Thread(o => { for (int j = 12000; j < mstrlist.Count; j++) { lock (synObj) { text += mstrlist[j] + ","; } } Dispatcher.BeginInvoke(new Action(() => { if (i == 4) txt.Text = text; else i++; })); }) { IsBackground = true }.Start(); }

用上面的方式的话,可以根据业务处理的难易度来选择要开多少个线程来处理,当然开的线程越多,处理的速度就越快,但是对资源的占用也越大。

下面再看看如何用线程池来处理同样的业务:

        private int conplate1 = 0;
        private Dictionary<string, string> mdd = null;
        private event tempChange OntempChange1;
        private int Conplate1
        {
            set
            {
                conplate1 = value;
            if (2 == value)
                OntempChange1(this, new EventArgs());
            }
            get { return conplate1; }
        }
private void Button_Click1(object sender, RoutedEventArgs e)
        {
            txt.Text = "";
            conplate1 = 0;
            parmar p = new parmar(1, 10000);
            ThreadPool.QueueUserWorkItem(new WaitCallback(InitList), p);
            parmar p1 = new parmar(10000, 20000);
            ThreadPool.QueueUserWorkItem(new WaitCallback(InitList), p1);
        }
        private void InitList(object o)
        {
            object synObj = new object();
            parmar p = o as parmar;
            for (int i = p.start; i < p.end; i++)
            {//这里一定要对mdd进行锁定,否则在线程池中的操作会导致有些项没有添加进去
                lock (mdd) { mdd.Add(i.ToString(), i.ToString()); }
            }
            this.Dispatcher.BeginInvoke(new Action(() => { Conplate1++; }));
        }
        private void ven_OntempChange1(object sender, EventArgs e)
        {
            int i = 1;
            string text = "";
            object synObj = new object();
            new Thread(o =>
            {
                for (int j = 1; j < 1000; j++)
                {
                    lock (synObj) { text += mdd[j.ToString()] + ","; }
                }
                Dispatcher.BeginInvoke(new Action(() =>
                {
                    if (i == 4)
                        txt.Text = text;
                    else
                        i++;
                }));
            }) { IsBackground = true }.Start();

            new Thread(o =>
            {
                for (int j = 1000; j < 5000; j++)
                {
                    lock (synObj) { text += mdd[j.ToString()] + ","; }
                }
                Dispatcher.BeginInvoke(new Action(() =>
                {
                    if (i == 4)
                        txt.Text = text;
                    else
                        i++;
                }));
            }) { IsBackground = true }.Start();
            new Thread(o =>
            {
                for (int j = 5000; j < 12000; j++)
                {
                    lock (synObj) { text += mdd[j.ToString()] + ","; }
                }
                Dispatcher.BeginInvoke(new Action(() =>
                {
                    if (i == 4)
                        txt.Text = text;
                    else
                        i++;
                }));
            }) { IsBackground = true }.Start();
            new Thread(o =>
            {
                for (int j = 12000; j <= mdd.Count; j++)
                {
                    lock (synObj) { text += mdd[j.ToString()] + ","; }
                }
                Dispatcher.BeginInvoke(new Action(() =>
                {
                    if (i == 4)
                        txt.Text = text;
                    else
                        i++;
                }));
            }) { IsBackground = true }.Start();
        }
//另外还需要一个参数类
public class parmar{
        public int start;
        public int end;
        public parmar(int s, int ed)
        {
            start = s;
            end = ed;
        }
    }

 

posted @ 2016-01-20 09:59  你爱我像谁  阅读(1605)  评论(0编辑  收藏  举报