zoukankan      html  css  js  c++  java
  • 用多线程处理后台业务,并提高处理速度

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

    假设现在后台需要处理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;
            }
        }
  • 相关阅读:
    Atitit 图像金字塔原理与概率 attilax的理解总结qb23
    Atiti  attilax主要成果与解决方案与案例rsm版 v4
    Atitit 常用比较复杂的图像滤镜 attilax大总结
    Atitit. Api 设计 原则 ---归一化
    Atitit 面向对象弊端与问题 坏处 缺点
    Atitit  记录方法调用参数上下文arguments
    Atitit 作用域的理解attilax总结
    Atitit usrQBM1603短信验证码规范
    atitit 短信验证码的源码实现  .docx
    Atitit 图片 验证码生成attilax总结
  • 原文地址:https://www.cnblogs.com/jin-/p/5144154.html
Copyright © 2011-2022 走看看