要实现的功能是:要对10个客户端发送信息,都是单独建立线程的,但是每次只能发送2个客户端,剩余的需要排队。同时如果有10个人同时使用这个功能的话,每个人建一个线程,每次只能同时2个人发送信息,剩余8个人要排队,只有当1个人的10个客户端发送完毕后,才能让下一个人进入这个功能。实现过程是:对应每个人建立一个线程,在这个线程里面在对应10台柜子来建立10个线程,这里的意思是先控制使用人数,然后再控制每个人发送的客户端数。不知道我说的大家明白不,请大家提供下思路,最主要的是每个人建立的10个线程数和那个人的对应的线程怎么关联起来。或者大家有什么好的实现方法,请赐教!不需要完整代码,有关键的控制并发代码即可!

解决方案 »

  1.   

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;namespace treadTest
    {    
        //定义委托
        public delegate void ListBoxDelegate(); 
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
            //委托处理方法(关联与ListBoxDelegate)
            private void ListBox()
            {
                if (!listBox1.InvokeRequired)//如果在UI主线程操作ListBox,
                {
                    listBox1.Items.Add(++CommonData.num);//则直接进行控件操作,“与UI主线程相关联”
                    listBox1.SelectedItem = listBox1.Items[listBox1.Items.Count - 1]; 
                }
                else//如果是在另一线程操作ListBox,则启用委托
                    listBox1.Invoke(new ListBoxDelegate(listShow));
            }
            
            //定义对UI主线程控件的操作,“与AddAuto相关联”。
            private void listShow()
            {
                listBox1.Items.Add(CommonData.num);
                listBox1.SelectedItem = listBox1.Items[listBox1.Items.Count - 1]; 
            }
            //定义线程函数
            private void AddAuto()
            {
                while (CommonData.Flag == 0)
                {
                    CommonData.num++;
                    Thread.Sleep(1000);
                    ListBox();//不能直接控制UI上的控件,所以用该方法选择使用委托
                }
            }
            //在click事件中启动多线程
            private void btnStart_Click(object sender, EventArgs e)
            {
                //线程标志置0,表示开启线程
                CommonData.Flag = 0;
                //定义 ThreadStart的委托类型的参数,并使该委托指向线程函数
                ListBoxDelegate mycn = new ListBoxDelegate(AddAuto);
                //实例化线程
                Thread insertTxt = new Thread(new ThreadStart(mycn));
                //启动线程
                insertTxt.Start();      
            }        private void btnAbort_Click(object sender, EventArgs e)
            {
                CommonData.Flag = 1;
            }
            private void btnCtrlMain_Click(object sender, EventArgs e)
            {
                ListBox();
            }
            private void btnReset_Click(object sender, EventArgs e)
            {
                CommonData.num = 0;
            }
            private void btnClear_Click(object sender, EventArgs e)
            {
                listBox1.Items.Clear();
            }
            private void btnQuit_Click(object sender, EventArgs e)
            {
                Application.Exit();
            }
        }
        
        //全局变量解决方案
        public class CommonData
        {
            private static int _Flag = 0;
            private static int _num = 0;
            public static int Flag
            {
                get { return _Flag; }
                set { _Flag = value; }
            }
            public static int num
            {
                get { return _num; }
                set { _num = value; }
            }
        }
    } 总结:        要使用多线程控制UI控件,必须用委托实现。调用控件的Invoke方法(Invoke方法的参数是一个委托类型的参数)。实现步骤:         1.声明委托。          2.声明委托处理函数(判断是主线程控制UI控件,还是Invoke(多线程)控制UI控件)。         3.声明一个线程实例,将线程函数的委托传入ThreadStart()。         4.开启该线程。         5.定义该线程函数,欲控制UI控件,则调用第2步的委托处理函数,他将自己判断选择用Invoke。         6.定义Invoke需要调用的函数(如本例的listShow函数)//*********************************************************************************************************************************      在上例中,只是完成了多线程控制主线程控件的功能,如果能手动和自动同时访问全局变量时,就有可能出现线程不同步的问题。以下主要利用lock线程锁来修改解决方案,使线程同步,注意代码带动的地方。using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;namespace treadTest
    {    
        //定义委托
        public delegate void ListBoxDelegate(); 
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
            //委托处理方法(关联与ListBoxDelegate)
            private void ListBox()
            {
                if (!listBox1.InvokeRequired)//如果在UI主线程操作ListBox,
                {
                    listBox1.Items.Add(CommonData.plus());//则直接进行控件操作,“与UI主线程相关联”
                    listBox1.SelectedItem = listBox1.Items[listBox1.Items.Count - 1]; 
                }
                else//如果是在另一线程操作ListBox,则启用委托
                    listBox1.Invoke(new ListBoxDelegate(listShow));
            }
            
            //定义对UI主线程控件的操作,“与AddAuto相关联”。
            private void listShow()
            {
                listBox1.Items.Add(CommonData.plus());
                listBox1.SelectedItem = listBox1.Items[listBox1.Items.Count - 1]; 
            }
            //定义线程函数
            private void AddAuto()
            {
                while (CommonData.Flag == 0)
                {
                    Thread.Sleep(1000);
                    ListBox();//不能直接控制UI上的控件,所以用该方法选择使用委托
                }
            }
            //在click事件中启动多线程
            private void btnStart_Click(object sender, EventArgs e)
            {
                //线程标志置0,表示开启线程 www.wanxinyi.com
                CommonData.Flag = 0;
                //定义 ThreadStart的委托类型的参数,并使该委托指向线程函数
                ListBoxDelegate mycn = new ListBoxDelegate(AddAuto);
                //实例化线程
                Thread insertTxt = new Thread(new ThreadStart(mycn));
                //启动线程
                insertTxt.Start();      
            }        private void btnAbort_Click(object sender, EventArgs e)
            {
                CommonData.Flag = 1;
            }
            private void btnCtrlMain_Click(object sender, EventArgs e)
            {
                ListBox();
            }
            private void btnReset_Click(object sender, EventArgs e)
            {
                CommonData.num = 0;
            }
            private void btnClear_Click(object sender, EventArgs e)
            {
                listBox1.Items.Clear();
            }
            private void btnQuit_Click(object sender, EventArgs e)
            {
                Application.Exit();
            }
        }
        
        //全局变量解决方案  www.shiapifa.com
        public class CommonData
        {
            private static int _Flag = 0;
            private static int _num = 0;
            public static int plus()
            {
                lock (new object())
                {
                    return _num++;
                }
            }
            public static int Flag
            {
                get { return _Flag; }
                set { _Flag = value; }
            }
            public static int num
            {
                get { return _num; }
                set { _num = value; }
            }
        }
    }
      

  2.   


    恩,控制人数的,目前是你这个意思,也就是2个线程,每个人对应一个线程,分别控制各自的任务,因为任务里面需要设置并发,我现在做的是,先new 10个线程,但只是让2个线程跑,已实现,想请问下,每个人对应的线程和这个线程new出来的10个线程,有办法关联不,就是说怎么控制这10个线程执行完了之后,那个人的线程才能释放,让给下一组人进来实现
      

  3.   

    主线程 new 2个线程(人1,人2),这2个线程是对应人数的,可以并发,然后这2个线程(人1,人2)里面每个在new 10个线程,这10个线程每次执行2个,等10个执行完之后,对应人的线程(人1,人2)才能释放,(人1,人2)2个线程new出来的20个线程怎么分别和对应人的线程联系起来,不让人2里面new出来的线程抢占人1里面的资源
      

  4.   


    这样不行,问题就是任务也需要同步并发,要向10个客户端发送信息,但是每次只能发送2个,不能是for循环遍历,还有人数控制那,也不能循环遍历,我这里说的数字只是举例子,可能是1000个人同时点,让100个人并发,后面的每个人的任务里面也可能是1000个客户端,100个并发
      

  5.   

    线程1,2从任务队列1里边取任务处理,如果任务队列1为空从基友队列取下下一个基友的任务装入任务队列1
    需要怎么控制呢,C#里面有没有什么关键字能搞的或者什么思路,我玩C#才半年,弄的是MVC3 ,给点提示
      

  6.   

    全部放入线程方法里处理就行,你可以写两个方法,一个处理任务队列1 一个处理任务队列2, 主线程首先填充基友队列,然后把4个工作线程全部启动起来,主要就是访问基友队列和任务队列的时候要同步,用来Lock锁定,.net 4里也有专门给线程间排他访问定义的泛型System.Generic.Concurrent命名空间底下
      

  7.   

    C# 中有没有,一个线程建立多个线程之后,要等多个线程执行完了,然后在执行主线程的方法啊,貌似有个join,只能是一个线程建立单个线程,单个线程执行完了,才会执行主线程,如果建立的是多个线程呢